Leon 1 год назад
Родитель
Сommit
7110bc4557

+ 4 - 4
src/_health/components/no_record.tsx

@@ -4,12 +4,12 @@ import { rpxToPx } from "@/utils/tools";
 import { MainColorType } from "@/context/themes/color";
 import { useTranslation } from "react-i18next";
 
-export default function NoRecord() {
-    const {t} = useTranslation()
+export default function NoRecord(props: { style?: any }) {
+    const { t } = useTranslation()
 
-    return <View className="no_more_bg">
+    return <View className="no_more_bg" style={{ ...props.style }}>
         {/* <Image style={{width:rpxToPx(160),height:rpxToPx(160)}} src={require('@assets/_health/null.png')}/> */}
         <View style={{ height: rpxToPx(188) }} />
-        <View className="h30 bold g03">{t('health.no_data')}</View>
+        <View className="h44 bold g03">{t('health.no_data')}</View>
     </View>
 }

+ 22 - 3
src/_health/pages/move_detail.tsx

@@ -12,6 +12,14 @@ import { MainColorType } from "@/context/themes/color";
 import ListFooter from "../components/list_footer";
 import { IconActive, IconSit } from "@/components/basic/Icons";
 import { useTranslation } from "react-i18next";
+import isToday from 'dayjs/plugin/isToday';
+import isTomorrow from 'dayjs/plugin/isTomorrow'
+import isYesterday from 'dayjs/plugin/isYesterday'
+
+
+dayjs.extend(isToday);
+dayjs.extend(isTomorrow);
+dayjs.extend(isYesterday);
 
 let useRoute;
 let useNavigation;
@@ -156,11 +164,22 @@ export default function MoveDetail() {
     function headerTitle() {
         const date = data.start_date + ''
         var strDate = date.substring(0, 4) + '-' + date.substring(4, 6) + '-' + date.substring(6, 8)
-        if (global.language == 'en'){
-            return dayjs(new Date(strDate).getTime()).format('MMMM D, YYYY')
+        var dayObj = dayjs(new Date(strDate).getTime())
+
+        if (dayObj.isToday()){
+            return global.language == 'en'?'Today':'今天'
+        }
+        else if (dayObj.isYesterday()){
+            return global.language == 'en'?'Yesterday':'昨天'
+        }
+        else if (new Date(strDate).getFullYear()==new Date().getFullYear()){
+            return global.language == 'en'?dayObj.format('MMMM D'):dayObj.format('MMMD日')
+        }
+        if (global.language == 'en') {
+            return dayObj.format('MMMM D, YYYY')
         }
         else {
-            return dayjs(new Date(strDate).getTime()).format('YYYY年MMMD日')
+            return dayObj.format('YYYY年MMMD日')
         }
 
         // return date.substring(0, 4) + '年' + date.substring(4, 6) + '月' + date.substring(6, 8) + '日'

+ 1 - 1
src/_moment/pages/message.tsx

@@ -119,7 +119,7 @@ export default function Message() {
   }
 
   if (loaded && list.length == 0)
-    return <NoRecord />
+    return <NoRecord style={{marginTop:rpxToPx(160)}}/>
 
   return <ScrollView style='height:100vh'
     enableBackToTop

+ 5 - 6
src/_moment/pages/relation.tsx

@@ -229,7 +229,7 @@ export default function Relation() {
             jumpPage('./home?uid=' + item.id)
         }}>
             <Image src={item.avatar} className="relation_avatar" />
-            <Text className="h34" style={{ color: MainColorType.link, flex: 1 }}>{item.nickname}</Text>
+            <Text className="h34 bold" style={{ color: MainColorType.link, flex: 1 }}>{item.nickname}</Text>
             {/* <Text>{item.relation}</Text> */}
             {
                 item.relation == 'FRIEND' && <Text className="h30 g02">Friend</Text>
@@ -242,7 +242,6 @@ export default function Relation() {
                     title="Follow"
                     type={NewButtonType.alpha}
                     color={MainColorType.blue}
-                    width={rpxToPx(136)}
                     height={rpxToPx(72)}
                     onClick={() => {
                         tapFollow(item)
@@ -287,17 +286,17 @@ export default function Relation() {
                 />
                 <View style={{ display: 'flex', flexDirection: 'row', height: 44, alignItems: 'center', justifyContent: 'center' }}>
                     <View className="relation_tab_item" onClick={() => { setIndex(0) }}>
-                        <View style={{ color: index == 0 ? '#000' : MainColorType.g02, fontWeight: 'bold' }}>搭子</View>
+                        <View className="h34 bold" style={{ color: index == 0 ? '#000' : MainColorType.g02 }}>Friend</View>
                         <View className={index == 0 ? 'sel_line1' : 'line'}></View>
                     </View>
 
                     <View className="relation_tab_item" onClick={() => { setIndex(1) }}>
-                        <View style={{ color: index == 1 ? '#000' : MainColorType.g02, fontWeight: 'bold' }}>关注</View>
+                        <View className="h34 bold" style={{ color: index == 1 ? '#000' : MainColorType.g02 }}>Following</View>
                         <View className={index == 1 ? 'sel_line1' : 'line'}></View>
                     </View>
 
                     <View className="relation_tab_item" onClick={() => { setIndex(2) }}>
-                        <View style={{ color: index == 2 ? '#000' : MainColorType.g02, fontWeight: 'bold' }}>粉丝</View>
+                        <View className="h34 bold" style={{ color: index == 2 ? '#000' : MainColorType.g02 }}>Follower</View>
                         <View className={index == 2 ? 'sel_line1' : 'line'}></View>
                     </View>
                     {/* <View style={{ flex: 1, color: index == 0 ? '#000' : MainColorType.g02, textAlign: 'center' }} onClick={() => { setIndex(0) }}>搭子</View>
@@ -328,7 +327,7 @@ export default function Relation() {
                     userList()
                 }
                 {
-                    loaded && list.length == 0 && <NoRecord />
+                    loaded && list.length == 0 && <NoRecord style={{marginTop:rpxToPx(160)}}/>
                 }
 
                 {/* {

+ 10 - 0
src/app.tsx

@@ -47,6 +47,16 @@ const App: React.FC<PropsWithChildren> = ({ children }) => {
     else {
       global.shareTicket = null
     }
+    console.log('global.shareTicket', global.shareTicket)
+  })
+
+  useLaunch((res) => {
+    if (res.shareTicket) {
+      global.shareTicket = res.shareTicket
+    }
+    else {
+      global.shareTicket = null
+    }
   })
 
 

+ 2 - 0
src/context/locales/en.js

@@ -1227,5 +1227,7 @@ export default {
         my_moments:'My Moments',
         my_friends:'My Friends',
         notification:'Notifications',
+
+        moment_share_title:'Hi, let\'s be friends!',
     }
 }

+ 2 - 0
src/context/locales/zh.js

@@ -1228,5 +1228,7 @@ export default {
         my_moments:'我的主页',
         my_friends:'我的搭子',
         notification:'消息通知',
+
+        moment_share_title:'Hi, 快来成为我的搭子!',
     }
 }

+ 25 - 1
src/pages/moment/guide.scss

@@ -13,7 +13,10 @@
 }
 
 .friend_body{
-    height: 500px;
+    width: 558px;
+    height: 504px;
+    margin-top: 96px;
+    margin-bottom: 136px;
 }
 
 .friend_share_btn {
@@ -36,6 +39,27 @@
     margin-bottom: 24px;
 }
 
+.avatar_bg{
+    width: 200px;
+    height: 200px;
+    border-radius: 100px;
+    position: relative;
+    overflow: hidden;
+}
+
+.edit_nick{
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    height: 48px;
+    color: #fff;
+    text-align: center;
+    line-height: 48px;
+    font-size: 20px;
+    background-color: rgba($color: #000000, $alpha: 0.7);
+}
+
 .avatar{
     width: 200px;
     height: 200px;

+ 7 - 3
src/pages/moment/guide.tsx

@@ -1,13 +1,15 @@
 import NewButton, { NewButtonType } from "@/_health/base/new_button";
 import { MainColorType } from "@/context/themes/color";
 import { rpxToPx } from "@/utils/tools";
-import { Button, View, Image } from "@tarojs/components";
+import { Button, View, Image,Text } from "@tarojs/components";
 import './guide.scss'
 import { useSelector } from "react-redux";
 import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
+import { useTranslation } from "react-i18next";
 
 export default function FriendGuide() {
     const user = useSelector((state: any) => state.user);
+    const {t} = useTranslation()
 
     function goLogin() {
         jumpPage('/_account/pages/ChooseAuth')
@@ -24,13 +26,15 @@ export default function FriendGuide() {
     return <View className="friend_guide_content">
         <View className="avatar_bg" onClick={tapAvatar}>
             {
-                user.isLogin ? <Image className='avatar gray_bg' src={user.avatar} mode="aspectFill"/> : <Image className="avatar gray_bg" src={require('@/assets/images/user.png')}/>
+                user.isLogin ? <View className="avatar_bg"><Image className='avatar gray_bg' src={user.avatar} mode="aspectFill"/>
+                <Text className="edit_nick">{t('health.edit')}</Text>
+                </View> : <Image className="avatar gray_bg" src={require('@/assets/images/user.png')}/>
             }
         </View>
 
         <View className="h50 bold">和搭子们</View>
         <View className="h50 bold">分享彼此的日常生活</View>
-        <View className="friend_body" />
+        <Image className="friend_body" src="https://background-pictures.oss-cn-beijing.aliyuncs.com/inapp/friends_prompt.png"/>
         <View className="friend_share_btn_bg">
             <NewButton
                 onClick={goLogin}

+ 5 - 3
src/pages/moment/moment.tsx

@@ -5,7 +5,7 @@ import { rpxToPx } from "@/utils/tools";
 import { View, Text, Image, ScrollView, Button } from "@tarojs/components";
 import Taro, { useRouter, useShareAppMessage } from "@tarojs/taro";
 import { useDispatch, useSelector } from "react-redux";
-import { useEffect, useState } from "react";
+import { useEffect, useState, useTransition } from "react";
 import { followUser, getFriendDashBoard, getFriendMoments, getMyFriends } from "@/services/friend";
 import FriendGuide from "./guide";
 import EmptyContent from "./empty_content";
@@ -21,6 +21,7 @@ export default function Friend() {
     const dispatch = useDispatch();
     const user = useSelector((state: any) => state.user);
     const [loaded, setLoaded] = useState(false)
+    const {t} = useTranslation()
 
     const launchObj = Taro.getLaunchOptionsSync()
 
@@ -51,9 +52,10 @@ export default function Friend() {
                 console.log(global.shareData)
             }
             return {
-                title: user.nickname+': 快来和搭子们一起,分享彼此的日常生活',
+                // title: user.nickname+': 快来和搭子们一起,分享彼此的日常生活',
+                title:t('health.moment_share_title'),
                 path: '/pages/moment/moment?type=share&uid=' + user.id,
-                // imageUrl: imageUrl
+                imageUrl: global.moment_share_url
             }
         })
     }

+ 34 - 24
src/pages/moment/moment_item.tsx

@@ -69,18 +69,24 @@ export default function MomentItem(props: { data: any }) {
         }} mode="aspectFill" style={{ width: rpxToPx(width), height: rpxToPx(height) }} src={imgObj.url + scale} />
     }
 
+    const kSpace = rpxToPx(12)
+    const hasMedia = moment.media.length > 0
+    const hasLink = link && (link.ring || link.move)
+
+
     return <View className="moment_item">
         <Image className="moment_avatar" src={user.avatar} mode="aspectFill" onClick={goProfile} />
         <View className="moment_detail" onClick={goDetail}>
             <View className="h34 bold" style={{ color: MainColorType.link, marginBottom: rpxToPx(6) }} onClick={goProfile}>{user.nickname}</View>
             {
-                moment.title && <View className="h22 g02" style={{ marginBottom: rpxToPx(6) }}>{moment.title}</View>
+                moment.title && <View className="h26 g02">{moment.title}</View>
             }
             {
-                moment.description && <TimeTitleDesc time="" title='' desc={moment.description} />
+                moment.description && <View style={{ marginTop: rpxToPx(6) }}><TimeTitleDesc time="" title='' desc={moment.description} /></View>
             }
+
             {
-                moment.description && <View style={{ height: rpxToPx(12) }} />
+                hasMedia && <View style={{ padding: kSpace }} />
             }
 
             {
@@ -91,30 +97,34 @@ export default function MomentItem(props: { data: any }) {
             }
 
             {
-                link && link.ring && <View style={{ marginTop: rpxToPx(24) }}>
-                    <TargetProgress
-                        color={getThemeColor(link.window)}
-                        showRing={true}
-                        desc={link.ring.description}
-                        og={link.status == 'OG'}
-                        startTimestamp={link.ring.start_timestamp}
-                        endTimerstamp={link.ring.end_timestamp ?? new Date().getTime()}
-                    />
-                </View>
+                hasLink && <View style={{ padding: kSpace }} />
             }
+
             {
-                link && link.move && <View style={{ marginTop: rpxToPx(24) }}>
-                    <TargetProgress
-                        color={getThemeColor(link.window)}
-                        showRing={false}
-                        desc={link.move.description}
-                        icon={
-                            <IconActive color={MainColorType.active} width={rpxToPx(32)} />
-                        }
-                    />
-                </View>
+                link && link.ring &&
+                <TargetProgress
+                    color={getThemeColor(link.window)}
+                    showRing={true}
+                    desc={link.ring.description}
+                    og={link.status == 'OG'}
+                    startTimestamp={link.ring.start_timestamp}
+                    endTimerstamp={link.ring.end_timestamp ?? new Date().getTime()}
+                />
+
+            }
+            {
+                link && link.move &&
+                <TargetProgress
+                    color={getThemeColor(link.window)}
+                    showRing={false}
+                    desc={link.move.description}
+                    icon={
+                        <IconActive color={MainColorType.active} width={rpxToPx(32)} />
+                    }
+                />
             }
-            <View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', marginTop: rpxToPx(24) }}>
+            <View style={{ padding: kSpace }} />
+            <View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between',alignItems:'center',height:rpxToPx(44) }}>
                 <View className="h26 g02">{dayjs(moment.timestamp).fromNow()}</View>
                 <View style={{ position: 'relative' }}>
                     <Button className="item_share" openType="share" onClick={() => { global.shareData = '9527'; console.log('sgareeeeeee') }}></Button>

+ 7 - 23
src/pages/moment/moment_main.tsx

@@ -21,6 +21,7 @@ import ListFooter from "@/_health/components/list_footer";
 import { MainColorType } from "@/context/themes/color";
 import dayjs from "dayjs";
 import { IconClose, IconMenu } from "@/components/basic/Icons";
+import MomentShare from "./moment_share";
 
 
 
@@ -103,12 +104,10 @@ export default function MomentMain() {
     }, [])
 
     function listenFollowUser(e) {
-        console.log('home follow user', e)
         myFriends()
     }
 
     function listenUnfollowUser(e) {
-        console.log('home unfollow user', e)
         myFriends()
     }
 
@@ -116,16 +115,11 @@ export default function MomentMain() {
 
     useEffect(() => {
         myFriends()
-        // const launchObj = Taro.getLaunchOptionsSync()
-        // console.log("heeee", router.params, launchObj)
         if (router.params.type == 'share') {
-            // console.log('share begin')
-            // console.log(launchObj)
             if (global.shareTicket) {
                 Taro.getShareInfo({
                     shareTicket: global.shareTicket,
                     success(result) {
-                        console.log('share info', result)
                         updateRelation(result)
                     },
                 })
@@ -146,7 +140,6 @@ export default function MomentMain() {
 
         observerObjBottom.observe('#footer', (res) => {
             setEndSignal(endSignal => endSignal + 1)
-            // console.log(moments.length)
             // if (moments.length==0) return
             // loadMore()
         })
@@ -158,8 +151,6 @@ export default function MomentMain() {
     }, [endSignal])
 
     function measureItemLayouts() {
-
-        console.log('开始计算位置', new Date().getTime(), moments.length)
         if (moments.length <= 10) {
             moments.forEach((item, index) => {
                 query.select(`#history2-${index}`).boundingClientRect()
@@ -175,7 +166,6 @@ export default function MomentMain() {
                 });
                 setItemLayouts(layouts)
                 setItemHeights(heights)
-                console.log('结束计算位置', new Date().getTime())
             })
         }
         else {
@@ -187,7 +177,6 @@ export default function MomentMain() {
             query.exec((res) => {
                 var layouts: any = []
                 var heights: any = []
-                // console.log(res)
                 res.forEach((rect, index) => {
 
                     if (rect) {
@@ -197,7 +186,6 @@ export default function MomentMain() {
                 });
                 setItemLayouts([...itemLayouts, ...layouts])
                 setItemHeights([...itemHeights, ...heights])
-                console.log('结束计算位置', new Date().getTime())
             })
 
         }
@@ -243,13 +231,10 @@ export default function MomentMain() {
             limit: 10
         }).then(res => {
             setIsPulling(false)
-            console.log(index)
             if (index == 1) {
-                console.log('ss')
                 setMoments((res as any).data)
             }
             else {
-                console.log('ooo')
                 setMoments([...moments, ...(res as any).data])
             }
             setLoading(false)
@@ -302,7 +287,6 @@ export default function MomentMain() {
         if (loading) return;
         if (noMore) return;
         setLoading(true)
-        console.log(page)
         var index = page;
         index++;
         setPage(index)
@@ -337,14 +321,14 @@ export default function MomentMain() {
             }}>关闭</View> */}
             {
                 user.isLogin && <View style={{
-                    position: 'absolute', left: 0, top: navigationBarHeight-44, width: 44, height: 44,
+                    position: 'absolute', left: 10, top: navigationBarHeight-44, width: 44, height: 44,
                     display: 'flex', alignItems: 'center', justifyContent: 'center'
                 }}
                     onClick={() => {
                         setCloseGuide(true)
                     }}
                 >
-                    <IconClose color="#000" width={20} height={20} />
+                    <IconClose color="#000" width={30} height={30} />
                 </View>
             }
 
@@ -359,14 +343,14 @@ export default function MomentMain() {
             <View style={{ height: navigationBarHeight, width: rpxToPx(750), backgroundColor: '#fff' }} />
             {
                 user.isLogin && <View style={{
-                    position: 'absolute', left: 0, top: navigationBarHeight-44, width: 44, height: 44,
+                    position: 'absolute', left: 10, top: navigationBarHeight-44, width: 44, height: 44,
                     display: 'flex', alignItems: 'center', justifyContent: 'center'
                 }}
                     onClick={() => {
                         setCloseGuide(true)
                     }}
                 >
-                    <IconClose color="#000" width={20} height={20} />
+                    <IconClose color="#000" width={30} height={30} />
                 </View>
             }
             <EmptyContent friends={dashBoard.friends} />
@@ -376,8 +360,6 @@ export default function MomentMain() {
         </View>
     }
 
-    // console.log(pageTop, itemLayouts)
-
     function listDetail() {
         return <View >
             <View style={{
@@ -563,9 +545,11 @@ export default function MomentMain() {
     }
 
     return <View>
+        
         {
             content()
         }
+        <MomentShare />
 
     </View>
 

+ 123 - 0
src/pages/moment/moment_share.tsx

@@ -0,0 +1,123 @@
+import { useDispatch, useSelector } from "react-redux";
+import { useEffect, useState } from "react";
+import { View, Canvas } from "@tarojs/components";
+import Taro from "@tarojs/taro";
+
+export default function MomentShare() {
+    const user = useSelector((state: any) => state.user);
+
+    const info = Taro.getWindowInfo ? Taro.getWindowInfo() : Taro.getSystemInfoSync()
+    const dpr = info.pixelRatio; // 获取设备的像素比
+
+
+    useEffect(() => {
+        if (user.isLogin) {
+            // beginDraw()
+            downCover()
+        }
+    }, [user])
+
+    async function downCover() {
+        const urls = ['https://background-pictures.oss-cn-beijing.aliyuncs.com/share_cover/invite.png', user.avatar]
+        try {
+            const imagePaths = await Promise.all(urls.map(downloadImage));
+            beginDraw(imagePaths);
+        } catch (error) {
+            console.error('下载图片错误:', error);
+        }
+    }
+
+    function downloadImage(url) {
+        return new Promise((resolve, reject) => {
+            Taro.downloadFile({
+                url,
+                success: (res) => {
+                    if (res.statusCode === 200) {
+                        resolve(res.tempFilePath);
+                    } else {
+                        reject(new Error('图片下载失败'));
+                    }
+                },
+                fail: (err) => {
+                    reject(err);
+                }
+            });
+        });
+    }
+
+    function beginDraw(imagePaths) {
+
+        const query = Taro.createSelectorQuery();
+        query.select(`#moment_share`).fields({ node: true, size: true });
+        query.exec((res) => {
+            const _canvas = res[0].node;
+            _canvas.width = res[0].width * dpr;
+            _canvas.height = res[0].height * dpr;
+            const ctx = _canvas.getContext('2d');
+            global.canvas2 = _canvas
+
+            drawDetail(ctx, imagePaths, _canvas)
+        });
+    }
+
+    function drawDetail(ctx, imagePaths, canvas) {
+        const promises = imagePaths.map((path, index) => {
+            return new Promise((resolve) => {
+                const img = canvas.createImage(); // 创建图像对象
+                img.src = path;
+                if (index == 0) {
+                    img.onload = () => {
+                        ctx.drawImage(img, 0, 0, 420 * dpr, 336 * dpr);
+                        ctx.stroke();
+                        resolve(true);
+                    };
+                }
+                else {
+                    img.onload = () => {
+                        ctx.font = `bold ${24 * dpr}px sans-serif`
+                        ctx.fillStyle = '#E0B152'
+                        ctx.textAlign = 'center'
+                        var name = user.nickname.length > 8 ? user.nickname.substring(0, 8) + '...' : user.nickname
+                        ctx.fillText(name, 210 * dpr, 182 * dpr);
+
+                        ctx.beginPath()
+                        ctx.arc(210 * dpr, 82 * dpr, 70 * dpr, 0, Math.PI * 2)
+                        ctx.clip()
+                        ctx.drawImage(img, 140 * dpr, 12 * dpr, 140 * dpr, 140 * dpr);
+                        ctx.restore()
+                        ctx.stroke();
+
+                        resolve(true);
+                    };
+                }
+
+            });
+        });
+
+        Promise.all(promises).then(() => {
+            // ctx.draw();
+
+            Taro.canvasToTempFilePath({
+                canvas: canvas,
+                success: (res) => {
+                    console.log('图片保存成功:', res.tempFilePath);
+                    global.moment_share_url = res.tempFilePath
+                },
+                fail: (err) => {
+                    console.error('转为图片失败:', err);
+                }
+            });
+            // 
+            // const ctx = Taro.createCanvasContext(this.canvasId);
+
+            // ctx.draw();
+        });
+
+        // ctx.drawImage(imagePaths[0], 0, 0, 420, 336) // 设置图片位置和大小
+        // ctx.draw()
+    }
+
+    return <View style={{ position: 'absolute', left: 0, top: -500, width: 420, height: 336, zIndex: 10000 }}>
+        <Canvas canvasId='moment_share' id='moment_share' className="canvas" type="2d" style={{ width: 420, height: 336, zIndex: 0 }} />
+    </View>
+}

+ 1 - 1
src/services/http/api.js

@@ -1,4 +1,4 @@
-const online = process.env.TARO_ENV == 'weapp' ? false : false;
+const online = process.env.TARO_ENV == 'weapp' ? true : false;
 
 import { WX_VERSION as _WX_VERSION, APP_VERSION as _APP_VERSION, ANDROID_VERSION as _ANDROID_VERSION } from "../../../config/env";