You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
6.9 KiB
138 lines
6.9 KiB
|
2 days ago
|
<template>
|
||
|
|
<view class="space-page">
|
||
|
|
<view class="nav" :style="{ paddingTop: menuButtonInfo.top + 'px' }">
|
||
|
|
<view class="back" @tap="back">‹</view>
|
||
|
|
<view class="nav-title">{{ ownerName }}的空间</view>
|
||
|
|
</view>
|
||
|
|
|
||
|
|
<view class="owner-card">
|
||
|
|
<image class="owner-avatar-img" v-if="ownerAvatarUrl" :src="ownerAvatarUrl" mode="aspectFill"></image>
|
||
|
|
<view class="owner-avatar" v-else>{{ ownerAvatarText }}</view>
|
||
|
|
<view class="owner-name">{{ ownerName }}</view>
|
||
|
|
<view class="owner-mode">{{ ownerMode === 'e' ? 'e 人 · 轻轻热闹' : 'i 人 · 安静陪伴' }}</view>
|
||
|
|
</view>
|
||
|
|
|
||
|
|
<view class="moment-empty" v-if="!moments.length && !loading">TA 还没有发过动态</view>
|
||
|
|
<view class="moment-card" v-for="item in moments" :key="item.id">
|
||
|
|
<view class="moment-time">{{ momentTime(item.createTime) }}</view>
|
||
|
|
<view class="moment-text" v-if="item.content">{{ item.content }}</view>
|
||
|
|
<view class="moment-grid" v-if="item.imageList && item.imageList.length" :class="'g' + item.imageList.length">
|
||
|
|
<image v-for="(img, idx) in item.imageList" :key="idx" :src="img" mode="aspectFill" @tap="previewImages(item, idx)"></image>
|
||
|
|
</view>
|
||
|
|
<view class="moment-video" v-if="item.videoUrl" @tap="playVideo(item)">
|
||
|
|
<image class="moment-video-poster" v-if="item.videoPoster" :src="item.videoPoster" mode="aspectFill"></image>
|
||
|
|
<view class="moment-video-holder" v-else></view>
|
||
|
|
<view class="moment-play">▶</view>
|
||
|
|
</view>
|
||
|
|
</view>
|
||
|
|
<view class="load-line" v-if="loading">加载中...</view>
|
||
|
|
<view class="load-line" v-else-if="!hasMore && moments.length">没有更多动态了</view>
|
||
|
|
</view>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
import { pageIeMoments } from '@/common/ieApi.js'
|
||
|
|
|
||
|
|
export default {
|
||
|
|
data() {
|
||
|
|
return {
|
||
|
|
menuButtonInfo: { top: 44 },
|
||
|
|
userId: null,
|
||
|
|
roomId: '',
|
||
|
|
ownerName: 'TA',
|
||
|
|
ownerAvatarText: 'TA',
|
||
|
|
ownerAvatarUrl: '',
|
||
|
|
ownerMode: 'i',
|
||
|
|
moments: [],
|
||
|
|
page: 1,
|
||
|
|
hasMore: true,
|
||
|
|
loading: false
|
||
|
|
}
|
||
|
|
},
|
||
|
|
onLoad(options = {}) {
|
||
|
|
if (uni.getMenuButtonBoundingClientRect) this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
||
|
|
this.userId = options.userId || null
|
||
|
|
this.roomId = options.roomId || ''
|
||
|
|
if (options.name) this.ownerName = decodeURIComponent(options.name)
|
||
|
|
if (options.avatar) this.ownerAvatarText = decodeURIComponent(options.avatar)
|
||
|
|
if (options.avatarUrl) this.ownerAvatarUrl = decodeURIComponent(options.avatarUrl)
|
||
|
|
if (options.mode) this.ownerMode = options.mode
|
||
|
|
this.loadMoments(true)
|
||
|
|
},
|
||
|
|
onReachBottom() {
|
||
|
|
this.loadMoments(false)
|
||
|
|
},
|
||
|
|
methods: {
|
||
|
|
back() {
|
||
|
|
uni.navigateBack({ fail: () => uni.redirectTo({ url: '/package1/ieBrowser/index' }) })
|
||
|
|
},
|
||
|
|
async loadMoments(reset) {
|
||
|
|
if (this.loading) return
|
||
|
|
if (!reset && !this.hasMore) return
|
||
|
|
if (!this.userId) return
|
||
|
|
this.loading = true
|
||
|
|
try {
|
||
|
|
const result = await pageIeMoments(this.userId, reset ? 1 : this.page, 10, this.roomId)
|
||
|
|
const records = (result && result.records) || []
|
||
|
|
this.moments = reset ? records : this.moments.concat(records)
|
||
|
|
this.hasMore = records.length >= 10
|
||
|
|
this.page = (reset ? 1 : this.page) + 1
|
||
|
|
const first = records.find(item => item.anonymousName)
|
||
|
|
if (first) {
|
||
|
|
this.ownerName = first.anonymousName || this.ownerName
|
||
|
|
this.ownerAvatarText = first.avatarText || this.ownerAvatarText
|
||
|
|
this.ownerAvatarUrl = first.avatarUrl || this.ownerAvatarUrl
|
||
|
|
this.ownerMode = first.currentMode || this.ownerMode
|
||
|
|
}
|
||
|
|
} finally {
|
||
|
|
this.loading = false
|
||
|
|
}
|
||
|
|
},
|
||
|
|
momentTime(timeStr) {
|
||
|
|
if (!timeStr) return ''
|
||
|
|
const time = new Date(String(timeStr).replace(/-/g, '/')).getTime()
|
||
|
|
if (!time) return ''
|
||
|
|
const diff = Date.now() - time
|
||
|
|
if (diff < 60000) return '刚刚'
|
||
|
|
if (diff < 3600000) return Math.floor(diff / 60000) + ' 分钟前'
|
||
|
|
if (diff < 86400000) return Math.floor(diff / 3600000) + ' 小时前'
|
||
|
|
if (diff < 172800000) return '昨天'
|
||
|
|
const d = new Date(time)
|
||
|
|
return (d.getMonth() + 1) + '月' + d.getDate() + '日'
|
||
|
|
},
|
||
|
|
previewImages(item, index) {
|
||
|
|
uni.previewImage({ urls: item.imageList || [], current: item.imageList[index] })
|
||
|
|
},
|
||
|
|
playVideo(item) {
|
||
|
|
if (!item.videoUrl) return
|
||
|
|
uni.navigateTo({ url: '/package1/ieBrowser/videoPreview?url=' + encodeURIComponent(item.videoUrl) })
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style lang="scss" scoped>
|
||
|
|
page { background: #f7f9ff; }
|
||
|
|
.space-page { min-height: 100vh; padding: 0 32rpx 80rpx; box-sizing: border-box; color: #161b2e; background: radial-gradient(circle at 50% 8%, rgba(169,255,231,.36), transparent 320rpx), linear-gradient(180deg, #fbfdff, #eef4ff 62%, #fff4e8); }
|
||
|
|
.nav { display: flex; align-items: center; padding-bottom: 16rpx; }
|
||
|
|
.back { width: 64rpx; height: 64rpx; line-height: 58rpx; text-align: center; border-radius: 50%; background: rgba(255,255,255,.7); font-size: 44rpx; color: rgba(22,27,46,.66); box-shadow: 0 10rpx 26rpx rgba(96,112,160,.12); }
|
||
|
|
.nav-title { margin-left: 20rpx; font-size: 32rpx; font-weight: 800; }
|
||
|
|
.owner-card { margin-top: 10rpx; padding: 34rpx; text-align: center; border-radius: 36rpx; background: rgba(255,255,255,.66); border: 1rpx solid rgba(255,255,255,.8); box-shadow: 0 20rpx 60rpx rgba(96,112,160,.12); }
|
||
|
|
.owner-avatar, .owner-avatar-img { width: 120rpx; height: 120rpx; margin: 0 auto; border-radius: 50%; }
|
||
|
|
.owner-avatar { line-height: 120rpx; text-align: center; background: linear-gradient(145deg, #effffb, #a9ffe7); font-size: 40rpx; font-weight: 800; color: #11162a; }
|
||
|
|
.owner-name { margin-top: 18rpx; font-size: 34rpx; font-weight: 800; }
|
||
|
|
.owner-mode { margin-top: 8rpx; color: #6c69d8; font-size: 23rpx; }
|
||
|
|
.moment-empty { margin-top: 60rpx; text-align: center; color: rgba(22,27,46,.4); font-size: 25rpx; }
|
||
|
|
.moment-card { margin-top: 24rpx; padding: 26rpx; border-radius: 28rpx; background: rgba(255,255,255,.85); border: 1rpx solid rgba(255,255,255,.9); box-shadow: 0 12rpx 32rpx rgba(96,112,160,.08); }
|
||
|
|
.moment-time { color: rgba(22,27,46,.42); font-size: 21rpx; }
|
||
|
|
.moment-text { margin-top: 14rpx; font-size: 27rpx; line-height: 42rpx; word-break: break-all; }
|
||
|
|
.moment-grid { display: flex; flex-wrap: wrap; margin-top: 16rpx; }
|
||
|
|
.moment-grid image { width: 196rpx; height: 196rpx; margin: 0 10rpx 10rpx 0; border-radius: 16rpx; background: rgba(22,27,46,.05); }
|
||
|
|
.moment-grid.g1 image { width: 400rpx; height: 400rpx; border-radius: 22rpx; }
|
||
|
|
.moment-grid.g2 image { width: 300rpx; height: 300rpx; }
|
||
|
|
.moment-video { position: relative; margin-top: 16rpx; width: 440rpx; height: 290rpx; border-radius: 22rpx; overflow: hidden; background: #1a2034; }
|
||
|
|
.moment-video-poster, .moment-video-holder { width: 100%; height: 100%; }
|
||
|
|
.moment-play { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 84rpx; height: 84rpx; line-height: 84rpx; text-align: center; border-radius: 50%; color: #fff; background: rgba(0,0,0,.45); font-size: 32rpx; }
|
||
|
|
.load-line { margin-top: 26rpx; text-align: center; color: rgba(22,27,46,.36); font-size: 22rpx; }
|
||
|
|
</style>
|