Files
PetCommunity/miniprogram/pages/profile/profile.ts

176 lines
4.8 KiB
TypeScript

import { Post, AppGlobalData } from '../../types/index'
import { api } from '../../utils/api'
import { getAvatarGradient, getPetEmoji, formatCount } from '../../utils/format'
const app = getApp<{ globalData: AppGlobalData }>()
Page({
data: {
statusBarHeight: 0,
navbarHeight: 44,
navbarPaddingRight: 0,
tabBarHeight: 56,
userInfo: {
nickName: '',
handle: '',
bio: '',
location: '',
stats: { posts: 0, friends: 0, likes: 0 },
pets: [],
} as any,
formattedLikes: '0',
avatarGradient: 'linear-gradient(135deg, #d9d2fb, #efedfd)',
posts: [] as Post[],
postView: 'grid' as 'grid' | 'list',
loading: false,
refreshing: false,
},
onLoad() {
const info = wx.getSystemInfoSync()
const { statusBarHeight, navbarHeight, navbarPaddingRight } = app.globalData.navBarInfo
this.setData({
statusBarHeight,
navbarHeight,
navbarPaddingRight,
tabBarHeight: info.windowHeight - (info.safeArea?.bottom ?? info.windowHeight) + 56,
})
this.loadProfile()
},
onShow() {
const tabBar = this.getTabBar() as any
tabBar?.setSelected?.(3)
this.syncFromGlobal()
},
syncFromGlobal() {
const user = app.globalData?.userInfo
if (!user) {
wx.redirectTo({ url: '/pages/login/login' })
return
}
const pets = (user.pets || []).map((p: any) => ({
...p,
emoji: getPetEmoji(p.species, p.breed),
gradient: getAvatarGradient(p._id),
}))
this.setData({
userInfo: { ...user, pets },
formattedLikes: formatCount(user.stats?.likes || 0),
avatarGradient: getAvatarGradient(user.openid || user._id || ''),
})
},
async loadProfile() {
this.setData({ loading: true })
try {
const [_user, postsRes] = await Promise.all([
api.getUserProfile(app.globalData?.userInfo?._id || '').catch(() => null),
api.getUserPosts(app.globalData?.userInfo?.openid || '').catch(() => ({ list: [], total: 0 })),
])
if (_user) {
app.globalData.userInfo = _user
this.syncFromGlobal()
}
this.setData({ posts: postsRes.list })
} catch {
} finally {
this.setData({ loading: false, refreshing: false })
}
},
setPostView(e: WechatMiniprogram.CustomEvent) {
this.setData({ postView: e.currentTarget.dataset.v as 'grid' | 'list' })
},
onStatTap(e: WechatMiniprogram.CustomEvent) {
const type = e.currentTarget.dataset.type
if (type === 'following') {
wx.switchTab({ url: '/pages/friends/friends' })
}
},
onGridItemTap(e: WechatMiniprogram.CustomEvent) {
const id = e.currentTarget.dataset.id
wx.navigateTo({ url: `/pages/post-detail/post-detail?id=${id}` })
},
onPetTap(e: WechatMiniprogram.CustomEvent) {
const pid = e.currentTarget.dataset.pid
wx.navigateTo({ url: `/pages/pet-edit/pet-edit?id=${pid}` })
},
onAddPet() {
wx.navigateTo({ url: '/pages/pet-edit/pet-edit' })
},
onEditProfile() {
wx.navigateTo({ url: '/pages/edit-profile/edit-profile' })
},
onEditAvatar() {
wx.showActionSheet({
itemList: ['从相册选取', '拍照'],
success: res => {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: [res.tapIndex === 0 ? 'album' : 'camera'],
success: async mediaRes => {
const path = mediaRes.tempFiles[0].tempFilePath
const cloudPath = `avatars/${app.globalData.userInfo?._id || Date.now()}.jpg`
wx.showLoading({ title: '上传中...' })
try {
const r = await wx.cloud.uploadFile({ cloudPath, filePath: path })
wx.hideLoading()
wx.showToast({ title: '头像已更新', icon: 'success' })
} catch {
wx.hideLoading()
wx.showToast({ title: '上传失败', icon: 'none' })
}
},
})
},
})
},
onSettings() {
wx.showActionSheet({
itemList: ['账号设置', '隐私设置', '退出登录'],
success: res => {
if (res.tapIndex === 2) {
wx.showModal({
title: '退出登录',
content: '确定要退出汪圈吗?',
success: modal => {
if (modal.confirm) {
wx.clearStorageSync()
app.globalData.userInfo = null
app.globalData.isLoggedIn = false
wx.redirectTo({ url: '/pages/login/login' })
}
},
})
}
},
})
},
onGoPost() {
wx.navigateTo({ url: '/pages/post/post' })
},
async onRefresh() {
this.setData({ refreshing: true })
await this.loadProfile()
},
onShareAppMessage() {
return {
title: `${this.data.userInfo.nickName}的汪圈主页`,
path: `/pages/pet-detail/pet-detail?userId=${app.globalData?.userInfo?._id}`,
}
},
})