156 lines
3.8 KiB
TypeScript
156 lines
3.8 KiB
TypeScript
import { Post } from '../../types/index'
|
|
import { api } from '../../utils/api'
|
|
import { getAvatarGradient, getPetEmoji } from '../../utils/format'
|
|
import { PAGE_SIZE } from '../../utils/constants'
|
|
|
|
interface FeedTab { key: 'feed' | 'nearby' | 'hot'; label: string }
|
|
|
|
const app = getApp<{ userInfo: any; currentLocation: any }>()
|
|
|
|
Page({
|
|
data: {
|
|
statusBarHeight: 0,
|
|
tabBarHeight: 56,
|
|
posts: [] as Post[],
|
|
stories: [] as any[],
|
|
activeTab: 'feed' as 'feed' | 'nearby' | 'hot',
|
|
feedTabs: [
|
|
{ key: 'feed', label: '关注' },
|
|
{ key: 'nearby', label: '附近' },
|
|
{ key: 'hot', label: '热门' },
|
|
] as FeedTab[],
|
|
loading: false,
|
|
loadingMore: false,
|
|
refreshing: false,
|
|
hasMore: true,
|
|
page: 0,
|
|
hasUnread: false,
|
|
myAvatarGradient: 'linear-gradient(135deg, #ffd6e8, #fff1a6)',
|
|
myEmoji: '🐶',
|
|
},
|
|
|
|
onLoad() {
|
|
const info = wx.getSystemInfoSync()
|
|
this.setData({
|
|
statusBarHeight: info.statusBarHeight,
|
|
tabBarHeight: info.windowHeight - info.safeArea.bottom + 56,
|
|
})
|
|
this.loadFeed(true)
|
|
this.loadStories()
|
|
this.syncMyInfo()
|
|
},
|
|
|
|
onShow() {
|
|
const tabBar = this.getTabBar() as any
|
|
tabBar?.setSelected?.(0)
|
|
},
|
|
|
|
onPullDownRefresh() {
|
|
this.onRefresh()
|
|
},
|
|
|
|
async onRefresh() {
|
|
this.setData({ refreshing: true, page: 0, hasMore: true })
|
|
await this.loadFeed(true)
|
|
this.setData({ refreshing: false })
|
|
},
|
|
|
|
async loadFeed(reset = false) {
|
|
if (!reset && !this.data.hasMore) return
|
|
if (this.data.loading && !reset) return
|
|
|
|
const page = reset ? 0 : this.data.page
|
|
this.setData(reset ? { loading: true } : { loadingMore: true })
|
|
|
|
try {
|
|
const loc = app.globalData?.currentLocation
|
|
const res = await api.getPosts({
|
|
page,
|
|
type: this.data.activeTab,
|
|
latitude: loc?.latitude,
|
|
longitude: loc?.longitude,
|
|
})
|
|
|
|
const posts = reset ? res.list : [...this.data.posts, ...res.list]
|
|
this.setData({
|
|
posts,
|
|
page: page + 1,
|
|
hasMore: res.hasMore,
|
|
})
|
|
} catch (e) {
|
|
wx.showToast({ title: '加载失败,下拉重试', icon: 'none' })
|
|
} finally {
|
|
this.setData({ loading: false, loadingMore: false })
|
|
}
|
|
},
|
|
|
|
async loadStories() {
|
|
try {
|
|
const res = await wx.cloud.callFunction({
|
|
name: 'getStories',
|
|
data: {},
|
|
}) as any
|
|
if (res.result?.code === 0) {
|
|
this.setData({ stories: res.result.data || [] })
|
|
}
|
|
} catch {}
|
|
},
|
|
|
|
syncMyInfo() {
|
|
const user = app.globalData?.userInfo
|
|
if (!user) return
|
|
const pet = user.pets?.[0]
|
|
this.setData({
|
|
myAvatarGradient: getAvatarGradient(user.openid || ''),
|
|
myEmoji: pet ? getPetEmoji(pet.species, pet.breed) : '🐶',
|
|
})
|
|
},
|
|
|
|
onSwitchTab(e: WechatMiniprogram.CustomEvent) {
|
|
const key = e.currentTarget.dataset.key as 'feed' | 'nearby' | 'hot'
|
|
if (key === this.data.activeTab) return
|
|
this.setData({ activeTab: key })
|
|
this.loadFeed(true)
|
|
},
|
|
|
|
onLoadMore() {
|
|
this.loadFeed(false)
|
|
},
|
|
|
|
onLikeChange(e: WechatMiniprogram.CustomEvent) {
|
|
const { postId, liked, count } = e.detail
|
|
const posts = this.data.posts.map(p =>
|
|
p._id === postId ? { ...p, isLiked: liked, likeCount: count } : p
|
|
)
|
|
this.setData({ posts })
|
|
},
|
|
|
|
onSearch() {
|
|
wx.navigateTo({ url: '/pages/search/search' })
|
|
},
|
|
|
|
onNotify() {
|
|
wx.navigateTo({ url: '/pages/notifications/notifications' })
|
|
},
|
|
|
|
onMyStory() {
|
|
wx.navigateTo({ url: '/pages/post/post?type=story' })
|
|
},
|
|
|
|
onStoryTap(e: WechatMiniprogram.CustomEvent) {
|
|
const id = e.currentTarget.dataset.id
|
|
wx.navigateTo({ url: `/pages/story/story?id=${id}` })
|
|
},
|
|
|
|
onGoPost() {
|
|
wx.navigateTo({ url: '/pages/post/post' })
|
|
},
|
|
|
|
onShareAppMessage() {
|
|
return {
|
|
title: '汪圈 — 宠物社区',
|
|
path: '/pages/feed/feed',
|
|
}
|
|
},
|
|
})
|