185 lines
12 KiB
Plaintext
185 lines
12 KiB
Plaintext
<view class="app-shell app-shell--secondary" style="{{layoutStyle}}">
|
||
<launch-transition />
|
||
<!-- pages/album/album.wxml -->
|
||
<app-nav title="相册详情" back="{{true}}" />
|
||
|
||
|
||
|
||
<scroll-view class="page-bg" scroll-y show-scrollbar="{{false}}" bounces="{{true}}" bindtouchstart="onTouchStart" bindtouchend="onTouchEnd" wx:if="{{!showUploadModal}}">
|
||
<view class="container"><view class="j-row"><view><text class="j-eyebrow">MOMENTS WE KEEP</text><text class="j-page-title">相册里的片段</text></view><button class="j-button j-button-small" bindtap="chooseImage">+ 照片</button></view>
|
||
<page-state wx:if="{{loading}}" kind="loading" title="正在加载" /><page-state wx:elif="{{loadError}}" kind="error" title="加载失败" description="请检查网络后重新加载" action="重试" bind:action="loadData" />
|
||
<view class="moments-list" wx:if="{{!loading && !loadError && batches.length > 0}}">
|
||
<view class="moments-item" wx:for="{{batches}}" wx:key="batch_id">
|
||
<view class="moments-avatar">
|
||
<image wx:if="{{item.creator_avatar}}" src="{{item.creator_avatar}}" mode="aspectFill" class="moments-avatar-img"></image>
|
||
<view class="avatar-circle" wx:else>{{item.creator_name}}</view>
|
||
</view>
|
||
<view class="moments-body">
|
||
<view class="moments-name-row">
|
||
<text class="moments-name">{{item.creator_name || '情侣'}}</text>
|
||
<text class="moments-count">{{item.photos.length}}张</text>
|
||
<view class="moments-more" data-batch="{{index}}" catchtap="openPhotoEditor" hover-class="moments-more-pressed" aria-role="button" aria-label="编辑照片信息"><text>•••</text></view>
|
||
</view>
|
||
<text class="moments-time moments-upload-time">上传于 {{item.created_time}}</text>
|
||
<view class="moments-images">
|
||
<view class="album-img-wrap" wx:for="{{item.photos}}" wx:key="id" wx:for-index="imgIdx" data-batch="{{index}}" data-index="{{imgIdx}}" bindtap="onPhotoTap" bindlongpress="onPhotoLongPress">
|
||
<image src="{{item.url}}" mode="aspectFill" class="album-img" />
|
||
</view>
|
||
</view>
|
||
<view class="moments-metadata {{item.metadataExpanded ? 'is-expanded' : ''}}" wx:if="{{item.metadata.length}}">
|
||
<block wx:for="{{item.metadata}}" wx:for-item="note" wx:for-index="noteIndex" wx:key="id">
|
||
<view class="moment-note" wx:if="{{item.metadataExpanded || noteIndex === 0}}">
|
||
<block wx:if="{{item.metadataExpanded}}">
|
||
<text class="moment-photo-label" wx:if="{{note.label}}">{{note.label}}</text>
|
||
<view class="moment-meta-row" wx:if="{{note.taken_at}}"><text class="moment-meta-label">拍摄</text><text class="moment-meta-value">{{note.taken_at}}</text></view>
|
||
<view class="moment-meta-row" wx:if="{{note.location}}"><text class="moment-meta-label">地点</text><text class="moment-meta-value">{{note.location}}</text></view>
|
||
<view class="moment-meta-row" wx:if="{{note.activity}}"><text class="moment-meta-label">故事</text><text class="moment-meta-value moment-story">{{note.activity}}</text></view>
|
||
</block>
|
||
<block wx:else>
|
||
<view class="moment-summary-line" wx:if="{{note.label || note.taken_at || note.location}}">
|
||
<text class="moment-summary-badge" wx:if="{{note.label}}">{{note.label}}</text>
|
||
<text class="moment-summary-date" wx:if="{{note.taken_at}}">{{note.taken_at}}</text>
|
||
<text class="moment-summary-location" wx:if="{{note.location}}">{{note.location}}</text>
|
||
</view>
|
||
<text class="moment-summary-story" wx:if="{{note.activity}}">{{note.activity}}</text>
|
||
</block>
|
||
</view>
|
||
</block>
|
||
<view class="moment-metadata-toggle" data-batch="{{index}}" catchtap="toggleMetadata" aria-role="button" aria-label="{{item.metadataExpanded ? '收起照片信息' : '展开照片信息'}}">
|
||
<text>{{item.metadataExpanded ? '收起详情' : (item.metadata.length > 1 ? '还有 ' + (item.metadata.length - 1) + ' 张照片信息 · 展开' : '展开详情')}}</text><text>{{item.metadataExpanded ? '⌃' : '⌄'}}</text>
|
||
</view>
|
||
</view>
|
||
<view class="moment-add-note" wx:else data-batch="{{index}}" catchtap="openPhotoEditor">+ 补充拍摄时间、地点和故事</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="empty-state" wx:if="{{!loading && !loadError && !batches.length}}">
|
||
<text>📷</text>
|
||
<text>还没有照片</text>
|
||
<text>点击上方添加照片</text>
|
||
</view>
|
||
</view>
|
||
|
||
</scroll-view>
|
||
|
||
<view class="preview-overlay" wx:if="{{showPreview}}" bindtap="closePreview">
|
||
<swiper class="preview-swiper" current="{{previewIndex}}" bindchange="onSwiperChange" circular bindtouchstart="onPreviewTouchStart" bindtouchend="onPreviewTouchEnd">
|
||
<swiper-item wx:for="{{previewImages}}" wx:key="*this">
|
||
<view class="preview-postcard" bindtap="closePreview" bindlongpress="onPostcardLongPress" data-url="{{item.url}}">
|
||
<view class="postcard-photo-frame">
|
||
<image src="{{item.url}}" mode="aspectFit" class="postcard-photo" />
|
||
<view class="postcard-seal">♥</view>
|
||
<view class="postcard-stamp" catchtap="closePreview">
|
||
<text class="stamp-heart">❤</text>
|
||
<text class="stamp-text">LOVE</text>
|
||
</view>
|
||
</view>
|
||
<view class="postcard-body">
|
||
<view class="postcard-rule" wx:if="{{item.taken_at}}">
|
||
<text class="rule-icon">📅</text>
|
||
<text class="rule-text">{{item.taken_at}}</text>
|
||
</view>
|
||
<view class="postcard-rule" wx:if="{{item.location}}">
|
||
<text class="rule-icon">📍</text>
|
||
<text class="rule-text">{{item.location}}</text>
|
||
</view>
|
||
<view class="postcard-rule" wx:if="{{item.activity}}">
|
||
<text class="rule-icon">💌</text>
|
||
<text class="rule-text">{{item.activity}}</text>
|
||
</view>
|
||
<view class="postcard-rule" wx:if="{{!item.taken_at && !item.location && !item.activity}}">
|
||
<text class="rule-text postcard-empty">— 我们past —</text>
|
||
</view>
|
||
<view class="postcard-footer">
|
||
<text class="footer-slogan">✦ 让所有的爱都有迹可循 ✦</text>
|
||
<text class="footer-hint">长按可保存原图</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</swiper-item>
|
||
</swiper>
|
||
<view class="preview-counter">{{previewIndex + 1}} / {{previewImages.length}}</view>
|
||
</view>
|
||
|
||
|
||
|
||
<!-- 全屏上传页 -->
|
||
<view wx:if="{{showUploadModal}}" class="upload-root" bindtouchstart="onUploadTouchStart" bindtouchend="onUploadTouchEnd">
|
||
<view class="upload-nav">
|
||
<view class="upload-back" catchtap="cancelUpload">
|
||
<image class="back-icon" src="/images/back.svg" mode="aspectFit" />
|
||
</view>
|
||
</view>
|
||
|
||
<scroll-view class="upload-body" scroll-y show-scrollbar="{{false}}">
|
||
<!-- 照片网格 -->
|
||
<view class="photo-grid">
|
||
<view class="photo-grid-item {{selectedPhotoIdx == index ? 'selected' : ''}}" wx:for="{{uploadFilePaths}}" wx:key="*this" bindtap="selectPhoto" data-index="{{index}}">
|
||
<image src="{{item}}" mode="aspectFill" class="photo-grid-img" />
|
||
<view class="photo-has-form" wx:if="{{photoFormList[index].taken_at || photoFormList[index].location || photoFormList[index].activity}}">✓</view>
|
||
<view class="photo-del-btn" catchtap="removePhoto" data-index="{{index}}">
|
||
<text class="photo-del-x">✕</text>
|
||
</view>
|
||
</view>
|
||
<!-- 添加更多 -->
|
||
<view class="photo-grid-item photo-grid-add" catchtap="addMorePhotos" wx:if="{{uploadFilePaths.length < 9}}">
|
||
<text class="add-plus">+</text>
|
||
<text class="add-label">添加</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 选中照片的表单 -->
|
||
<view class="upload-form-card" wx:if="{{uploadFilePaths.length > 0}}">
|
||
<view class="form-card-head">
|
||
<image src="{{uploadFilePaths[selectedPhotoIdx]}}" mode="aspectFill" class="form-preview" />
|
||
<text class="form-card-desc">为第 {{selectedPhotoIdx + 1}} 张照片填写信息</text>
|
||
</view>
|
||
<view class="input-group">
|
||
<label>拍摄时间</label>
|
||
<picker mode="date" value="{{uploadForm.taken_at}}" bindchange="onUploadInput" data-field="taken_at">
|
||
<view class="input">{{uploadForm.taken_at || '选择日期'}}</view>
|
||
</picker>
|
||
</view>
|
||
<view class="input-group">
|
||
<label>地点</label>
|
||
<input placeholder-class="handwritten-placeholder" class="input" placeholder="{{currentAddress || '留空自动使用当前地址'}}" value="{{uploadForm.location}}" bindinput="onUploadInput" data-field="location" />
|
||
</view>
|
||
<view class="input-group">
|
||
<label>在做什么</label>
|
||
<input placeholder-class="handwritten-placeholder" class="input" placeholder="例如:第一次一起看日落" value="{{uploadForm.activity}}" bindinput="onUploadInput" data-field="activity" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态提示(无照片时) -->
|
||
<view class="upload-empty" wx:if="{{uploadFilePaths.length == 0}}">
|
||
<text class="empty-icon">📷</text>
|
||
<text class="empty-desc">点击 + 添加照片</text>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<view class="upload-footer">
|
||
<button class="btn btn-primary" bindtap="uploadAll" hover-class="none" loading="{{uploading}}" wx:if="{{uploadFilePaths.length > 0}}">上传全部 ({{uploadFilePaths.length}}张)</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 照片信息编辑面板 -->
|
||
<view class="photo-editor-mask" wx:if="{{showPhotoEditor}}" catchtouchmove="preventEditorMove">
|
||
<view class="photo-editor-backdrop" catchtap="closePhotoEditor" />
|
||
<view class="photo-editor-sheet">
|
||
<view class="photo-editor-grip" />
|
||
<view class="photo-editor-head"><view><text class="photo-editor-title">给照片补一段故事</text><text class="photo-editor-caption">{{editPhotos.length > 1 ? '选择照片,分别记录它的时刻' : '留住这一天,也留住当时的心情'}}</text></view><view class="photo-editor-close" catchtap="closePhotoEditor" aria-role="button" aria-label="关闭">×</view></view>
|
||
<scroll-view class="photo-editor-body" scroll-y show-scrollbar="{{false}}">
|
||
<scroll-view class="photo-editor-picker" scroll-x show-scrollbar="{{false}}" wx:if="{{editPhotos.length > 1}}">
|
||
<view class="photo-editor-thumbs"><view wx:for="{{editPhotos}}" wx:key="id" class="photo-editor-thumb {{editPhotoIdx === index ? 'photo-editor-selected' : ''}}" data-index="{{index}}" catchtap="selectEditPhoto"><image src="{{item.url}}" mode="aspectFill" /><text>第 {{index + 1}} 张</text></view></view>
|
||
</scroll-view>
|
||
<view class="photo-editor-single" wx:else><image src="{{editPhotos[0].url}}" mode="aspectFill" /><text>编辑这张照片的信息</text></view>
|
||
<view class="photo-editor-field"><view class="photo-editor-label"><text>拍摄时间</text><text class="photo-editor-clear" wx:if="{{editForm.taken_at}}" catchtap="clearPhotoDate">清除</text></view><picker mode="date" value="{{editForm.taken_at}}" disabled="{{savingPhoto}}" bindchange="onEditPhotoInput" data-field="taken_at"><view class="photo-editor-input {{!editForm.taken_at ? 'photo-editor-placeholder' : ''}}">{{editForm.taken_at || '选择拍摄日期'}}<text>⌄</text></view></picker></view>
|
||
<view class="photo-editor-field"><text class="photo-editor-label">地点 · 留空使用当前地址</text><input class="photo-editor-input" placeholder="{{currentAddress || '留空自动使用当前地址'}}" placeholder-class="photo-editor-placeholder handwritten-placeholder" maxlength="200" value="{{editForm.location}}" disabled="{{savingPhoto}}" bindinput="onEditPhotoInput" data-field="location" /></view>
|
||
<view class="photo-editor-field"><text class="photo-editor-label">在做什么</text><textarea class="photo-editor-story" placeholder="例如:第一次一起看日落" placeholder-class="photo-editor-placeholder handwritten-placeholder" maxlength="200" value="{{editForm.activity}}" disabled="{{savingPhoto}}" bindinput="onEditPhotoInput" data-field="activity" fixed="{{true}}" adjust-position="{{true}}" /></view>
|
||
</scroll-view>
|
||
<view class="photo-editor-actions"><button class="photo-editor-cancel" bindtap="closePhotoEditor" disabled="{{savingPhoto}}">取消</button><button class="j-button photo-editor-save" bindtap="savePhotoInfo" loading="{{savingPhoto}}" disabled="{{savingPhoto}}">保存这张照片</button></view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|