Leon 1 år sedan
förälder
incheckning
bbcb57b3f7

+ 1 - 1
src/_account/pages/Album.tsx

@@ -193,7 +193,7 @@ export default function Album() {
             }
         }
         if (showDate) {
-            return <View className="history_year_month h42 bold">{dateStr2}</View>
+            return <View className="history_year_month h42 bold" style={{marginBottom:rpxToPx(60)}}>{dateStr2}</View>
         }
         return <View />
     }

+ 1 - 2
src/_health/base/new_date_time_picker.tsx

@@ -15,7 +15,6 @@ export default function NewDateTimePicker(props: {
     const [values, setValues] = useState<any>([0, 0, 0])
     const [loaded, setLoaded] = useState(false)
 
-
     function longDatas() {
         let result: any = []
         var max = props.maxTimestamp ?? new Date().getTime()
@@ -165,7 +164,7 @@ export default function NewDateTimePicker(props: {
                 return <PickerViewColumn key={index}>
                     {item.map((obj, j) => {
                         return (
-                            <Text key={j} style={{ display: 'flex',fontSize:rpxToPx(36), alignItems: 'center', justifyContent: 'center', color: getColor(index, j) ? props.color ?? MainColorType.fast : '#000' }}>{obj}</Text>
+                            <Text key={j} className="item_text" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: getColor(index, j) ? props.color ?? MainColorType.fast : '#000' }}>{obj}</Text>
                         );
                     })}
                 </PickerViewColumn>

+ 1 - 1
src/_health/base/new_durationpicker.tsx

@@ -169,7 +169,7 @@ export default function NewDurationPicker(props: { value?: any, onChange?: any,
                 return <PickerViewColumn key={index}>
                     {item.map((obj, j) => {
                         return (
-                            <Text key={j} style={{ display: 'flex',fontSize:rpxToPx(36), alignItems: 'center', justifyContent: 'center', color: getColor(index, j) ? props.color ?? MainColorType.fast : '#000' }}>{obj}</Text>
+                            <Text key={j}  className="item_text" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: getColor(index, j) ? props.color ?? MainColorType.fast : '#000' }}>{obj}</Text>
                         );
                     })}
                 </PickerViewColumn>

+ 5 - 1
src/_health/base/new_timepicker.scss

@@ -12,4 +12,8 @@
 /* #ifdef rn */
 .pick_sel_item {}
 
-/* #endif */
+/* #endif */
+
+.item_text{
+    font-size: 36px;
+}

+ 16 - 6
src/_health/components/target_progress.tsx

@@ -16,6 +16,7 @@ export default function TargetProgress(props: {
     showRing: boolean,
     icon?: any,
     desc?: string,
+    time_desc?: string,
     og?: boolean,
 
     //双环
@@ -172,12 +173,21 @@ export default function TargetProgress(props: {
                     }
                 </View>
         }
-        {
-            props.desc && <View className='history_item_duration h32'>{props.desc}</View>
-        }
-        {
-            props.og && <View className='history_item_duration h32'>{TimeFormatter.formateTimeDifference(props.startTimestamp!,props.endTimerstamp!)}</View>
-        }
+        <View>
+            <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
+                {
+                    props.desc && <View className='history_item_duration h32'>{props.desc}</View>
+                }
+                {
+                    props.og && <View className='history_item_duration h32'>{TimeFormatter.formateTimeDifference(props.startTimestamp!, props.endTimerstamp!)}</View>
+                }
+            </View>
+            {
+                props.time_desc && props.time_desc.length > 0 && <View className='h26 g02' style={{marginLeft:rpxToPx(10)}}>{props.time_desc}</View>
+            }
+        </View>
+
+
         {
             props.doubleRing && <View className='history_item_duration h32' style={{
                 display: 'flex',

+ 78 - 40
src/_health/pages/recents.tsx

@@ -12,12 +12,14 @@ import { useEffect, useRef, useState } from "react";
 import MainHistory from "@/features/health/MainHistory";
 import Taro from "@tarojs/taro";
 import { checkSummaries } from "@/services/health";
+import StickyDateList from "../components/sticky_date_list";
 
 export default function Recents() {
     const [mode, setMode] = useState('EAT')
     const { t } = useTranslation()
     const historyRef = useRef()
     const [list, setList] = useState<any>([])
+    const [isPulling,setIsPulling] = useState(false)
 
     useEffect(() => {
         getData()
@@ -36,46 +38,82 @@ export default function Recents() {
 
 
     function detail() {
-        return <View style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
-            <NewHeader type={NewHeaderType.left} title={t('health.check_ins')} />
-            <ScrollView style={{ width: rpxToPx(750), flexDirection: 'row', display: 'flex', height: rpxToPx(72) }} scrollX enableFlex showScrollbar={false}>
-                <View style={{display:'flex',flexDirection:'row',flexShrink:0}}>
-                    <View style={{ width: rpxToPx(40), flexShrink: 0 }} />
-                    {
-                        list.map((item, index) => {
-                            return <NewButton key={index} type={NewButtonType.img} onClick={() => setMode(item.window)}>
-                                <View className="streak_toolbar_btn"
-                                    style={{ backgroundColor: mode == item.window ? getThemeColor(item.window) + '1A' : 'transparent' }}
-                                >
-                                    <Text className={mode == item.window ? 'bold h30' : 'h30'}
-                                        style={{ color: mode == item.window ? getThemeColor(item.window) : MainColorType.g01, marginRight: 5 }}>{item.title}</Text>
-                                    <Text className={mode == item.window ? 'bold h20' : 'h20'}
-                                        style={{ color: mode == item.window ? getThemeColor(item.window) : MainColorType.g01 }}>{item.log_count}</Text>
-                                </View>
-                            </NewButton>
-                        })
-                    }
-                    <View style={{ width: rpxToPx(40), flexShrink: 0 }} />
-                </View>
-            </ScrollView>
-            <View style={{ height: rpxToPx(36), flexShrink: 0 }} />
-            <MainHistory ref={historyRef} type={mode} updateDate={(e) => {
-                // setShowDate(e.show)
-                // setDate(e.date)
-            }} />
-        </View>
+        return <StickyDateList
+            isPulling={isPulling}
+            showDate={false}
+            date={''}
+            onRefresherRefresh={() => {
+                global.refreshWindow()
+                setIsPulling(true)
+                if (global.refreshHistory) {
+                    global.refreshHistory()
+                }
+            }}
+            loadMore={() => {
+                if (historyRef) {
+                    (historyRef.current as any).more()
+                }
+            }}
+            onScroll={e => {
+                // props.onScroll(e)
+                // if (showDate && e.detail.scrollTop > 100) {
+                //     dispatch(setTitle(t('health.recents')))
+                // }
+                // else if (e.detail.scrollTop > 100) {
+                //     dispatch(setTitle(t('health.today')))
+                // }
+                // else {
+                //     dispatch(setTitle(''))
+                // }
+                // if (historyRef2) {
+                //     (historyRef2.current as any).onScroll(e)
+                // }
+                if (e.detail.scrollTop > 100){
+                    Taro.setNavigationBarTitle({
+                        title:t('health.check_ins')
+                    })
+                }
+                else {
+                    Taro.setNavigationBarTitle({
+                        title:''
+                    })
+                }
+            }}
+        ><View style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
+                <NewHeader type={NewHeaderType.left} title={t('health.check_ins')} />
+                <ScrollView style={{ width: rpxToPx(750), flexDirection: 'row', display: 'flex', height: rpxToPx(72) }} scrollX enableFlex showScrollbar={false}>
+                    <View style={{ display: 'flex', flexDirection: 'row', flexShrink: 0 }}>
+                        <View style={{ width: rpxToPx(40), flexShrink: 0 }} />
+                        {
+                            list.map((item, index) => {
+                                return <NewButton key={index} type={NewButtonType.img} onClick={() => setMode(item.window)}>
+                                    <View className="streak_toolbar_btn"
+                                        style={{ backgroundColor: mode == item.window ? getThemeColor(item.window) + '1A' : 'transparent' }}
+                                    >
+                                        <Text className={mode == item.window ? 'bold h30' : 'h30'}
+                                            style={{ color: mode == item.window ? getThemeColor(item.window) : MainColorType.g01, marginRight: 5 }}>{item.title}</Text>
+                                        <Text className={mode == item.window ? 'bold h20' : 'h20'}
+                                            style={{ color: mode == item.window ? getThemeColor(item.window) : MainColorType.g01 }}>{item.log_count}</Text>
+                                    </View>
+                                </NewButton>
+                            })
+                        }
+                        <View style={{ width: rpxToPx(40), flexShrink: 0 }} />
+                    </View>
+                </ScrollView>
+                <View style={{ height: rpxToPx(36), flexShrink: 0 }} />
+                <MainHistory ref={historyRef} type={mode} updateDate={(e) => {
+                    // setShowDate(e.show)
+                    // setDate(e.date)
+                }} />
+            </View>
+        </StickyDateList>
     }
+    return detail()
 
-    return <Layout children={detail()}
-        // title={router.params.title}
-
-        // secondPage={true}
-        // titleColor={'#fff'}
-        title={t('health.check_ins')}
-        type={TemplateType.customHeader}
-        // refresh={() => { refresh() }}
-        // triggered={triggered}
-        // more={() => { more() }}
-        titleShowStyle={NaviBarTitleShowType.scrollToShow}
-    />
+    // return <Layout children={detail()}
+    //     title={t('health.check_ins')}
+    //     type={TemplateType.customHeader}
+    //     titleShowStyle={NaviBarTitleShowType.scrollToShow}
+    // />
 }

+ 31 - 4
src/_health/pages/timeline_detail.tsx

@@ -34,10 +34,11 @@ import 'dayjs/locale/zh-cn';
 import 'dayjs/locale/en';
 import { getInfoSuccess } from "@/store/user";
 import LongCard from "@/_moment/components/long_card";
-import { setFollow } from "@/store/long";
+import { setFollow, setJoinData } from "@/store/long";
 import MomentDetailShare from "@/pages/moment/moment_detail_share";
 import { followUser } from "@/services/friend";
 import { setActions, setEvents, setTimeData } from "@/store/record";
+import ShareBtn from "@/components/basic/ShareBtn";
 
 let useRoute;
 let useNavigation;
@@ -1032,6 +1033,7 @@ export default function TimelineDetail() {
                                 color={getThemeColor(item.window)}
                                 showRing={detail.fast_type == 'LF' ? false : true}
                                 desc={item.description}
+                                time_desc={item.time_desc}
                                 icon={
                                     detail.fast_type == 'LF' ? <IconLongFast color={MainColorType.fast} width={rpxToPx(32)} /> : null
                                 }
@@ -1060,13 +1062,38 @@ export default function TimelineDetail() {
                             {/* <Text className="h24 g02">{publish.edited ? '编辑于' : '发布于'}{dayjs(publish.timestamp).format('M月D日 HH:mm')}</Text> */}
                             <Text className="h24 g02">{footerTime(publish)}</Text>
                             <View style={{ flex: 1 }} />
-                            <View className="share_btn_bg">
+                            {
+                                join && join.status == 'JOIN' && <NewButton type={NewButtonType.custom} onClick={() => {
+                                    if (!user.isLogin) {
+                                        jumpPage('/_account/pages/ChooseAuth')
+                                        return
+                                    }
+                                    dispatch(setFollow(shareUser ? shareUser : detail.share_user ? detail.share_user : user))
+                                    dispatch(setJoinData(join))
+                                    if (join.window == 'ACTIVE' || join.window == 'EAT') {
+                                        jumpPage(`/_record/pages/log_record?scenario=${join.window == 'EAT' ? 'MEAL' : 'ACTIVITY'}&join_id=${join.key}`)
+                                    }
+                                    else if (join.window == 'FAST' || join.window == 'SLEEP') {
+                                        jumpPage(`/_record/pages/time_record?scenario=${join.window}&join_id=${join.key}`)
+                                    }
+
+                                    // jumpPage(`/_moment/pages/long_detail?join_id=${join.key}&window=${join.window}&status=${join.status}`)
+                                }}>
+                                    <View className="h24" style={{ color: MainColorType.link, padding: rpxToPx(13) }}>跟卡</View>
+                                </NewButton>
+                            }
+                            {/* <View className="share_btn_bg">
 
-                                <View className="share_icon_bg">
+                                <View className="share_icon_bg" style={{ paddingLeft: rpxToPx(20), paddingRight: rpxToPx(20) }}>
                                     <IconShare color={MainColorType.link + 'cc'} width={rpxToPx(32)} />
                                 </View>
                                 <Button className="share_btn" openType="share">1</Button>
-                            </View>
+                            </View> */}
+                            <ShareBtn>
+                                <View className="share_icon_bg" >
+                                    <IconShare color={MainColorType.link + 'cc'} width={rpxToPx(32)} />
+                                </View>
+                            </ShareBtn>
 
 
                             {

+ 1 - 1
src/_moment/components/long_card.tsx

@@ -111,7 +111,7 @@ export default function LongCard(props: { join?: any, user?: any, hideJoin?: boo
         </View>
     }
 
-    if (status == 'JOIN')
+    if (/*status == 'JOIN' && */props.join && props.join.user_count>0)
         return <View onClick={goDetail} style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(24) }}>
             {
                 (props.join && props.join.user_count == 0) && <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>

+ 1 - 0
src/_moment/components/recent_item.tsx

@@ -88,6 +88,7 @@ export default function RecentItem(props: { data: any, index: number }) {
                             color={getThemeColor(link.window)}
                             showRing={true}
                             desc={link.ring.description}
+                            time_desc={link.ring.time_desc}
                             og={link.status == 'OG'}
                             startTimestamp={link.ring.start_timestamp}
                             endTimerstamp={link.ring.end_timestamp ?? new Date().getTime()}

+ 1 - 1
src/_record/components/picker_card.tsx

@@ -37,7 +37,7 @@ export default function PickerCard(props: { onClose: any, onConfirm: any, title:
                     }} />
                 }
                 {
-                    props.type == 'datetime' && <NewDateTimePicker color={MainColorType.orange} date={dayjs(value).format('YYYY-MM-DD')} count={1} time={dayjs(value).format('HH:mm')}
+                    props.type == 'datetime' && <NewDateTimePicker color={MainColorType.black} date={dayjs(value).format('YYYY-MM-DD')} count={1} time={dayjs(value).format('HH:mm')}
                         minTimestamp={new Date(props.value).getTime() - 24 * 3600 * 1000}
                         maxTimestamp={new Date().getTime()}
                         onChange={(e) => {

+ 22 - 4
src/_record/components/ring_progress.tsx

@@ -24,6 +24,7 @@ export default function RingProgress(props: {
     const dpr = info.pixelRatio; // 获取设备的像素比
     const [ctx, setCtx] = useState<any>(null)
     const [canvas, setCanvas] = useState<any>(null)
+    const [checkImg,setCheckImg] = useState<any>(null)
     const canvasRef = useRef(null);
 
 
@@ -120,6 +121,7 @@ export default function RingProgress(props: {
                 ctx.lineCap = 'round'; // 设置为圆角
                 ctx.stroke();
             }
+            console.log('begin draw real')
             ctx.beginPath();
             ctx.arc(canvasWidth / 2.0, canvasHeight / 2.0, props.radius, props.real.start, props.real.start + Math.max(props.real.duration, 0.01));
             ctx.lineWidth = props.real.width;
@@ -226,15 +228,31 @@ export default function RingProgress(props: {
 
         if (props.isCompleted) {
             if (_canvas) {
-                const img1 = _canvas.createImage(); // 创建图像对象
-                img1.src = global.checkImg
-                img1.onload = () => {
-                    ctx.drawImage(img1, rpxToPx(324), rpxToPx(60), rpxToPx(400), rpxToPx(340));
+
+                if (!checkImg){
+                    const img1 = _canvas.createImage(); // 创建图像对象
+                    img1.src = global.checkImg
+                    img1.onload = () => {
+                        console.log('begin draw img')
+                        ctx.beginPath();
+                        setCheckImg(img1)
+                        ctx.drawImage(img1, rpxToPx(324), rpxToPx(60), rpxToPx(400), rpxToPx(340));
+                        ctx.stroke();
+                        if (props.shareCover && _canvas) {
+                            save(_canvas)
+                        }
+                    }
+                }
+                else {
+                    console.log('begin draw img2')
+                    ctx.beginPath();
+                    ctx.drawImage(checkImg, rpxToPx(324), rpxToPx(60), rpxToPx(400), rpxToPx(340));
                     ctx.stroke();
                     if (props.shareCover && _canvas) {
                         save(_canvas)
                     }
                 }
+                
             }
         }
         else {

+ 3 - 2
src/_record/pages/log_record.scss

@@ -107,7 +107,7 @@
     height: 420px;
     width: 570px;
     box-sizing: border-box;
-    padding: 30px 0px;
+    // padding: 30px 0px;
     margin-top: 48px;
     margin-bottom: 48px;
 }
@@ -162,7 +162,7 @@
     flex-direction: row;
     align-items: center;
     margin-left: 56px;
-    padding-right: 28px;
+    padding-right: 52px;
     height: 108px;
 }
 
@@ -267,6 +267,7 @@
     min-height: 875px;
     border-radius: 84px;
     padding: 64px;
+    padding-bottom: 44px;
     box-sizing: border-box;
     display: flex;
     flex-direction: column;

+ 87 - 85
src/_record/pages/log_record.tsx

@@ -498,8 +498,8 @@ export default function LogRecord() {
             setShowResult(true)
             setResult(res)
             setPosting(false)
-            Taro.eventCenter.trigger('refresh_timeline',(res as any).feed_item)
-            if (global.refreshHistory){
+            Taro.eventCenter.trigger('refresh_timeline', (res as any).feed_item)
+            if (global.refreshHistory) {
                 global.refreshHistory()
             }
             Taro.navigateBack()
@@ -576,7 +576,7 @@ export default function LogRecord() {
                             setStep(2)
                             return
                         }
-                        if (step == 2) {
+                        if (step == 2 && (desc.length > 0 || pics.length > 0)) {
                             showAlert({
                                 title: t('health.back_no_save'),
                                 content: '',
@@ -685,18 +685,19 @@ export default function LogRecord() {
             </View>
         }
         {
-            step == 2 && <View className="cardShowAni">
+            step == 2 && <ScrollView style={{ flex: 1, position: 'relative', zIndex: 1000, height: screenHeight - navigationBarHeight - rpxToPx(276) }} scrollY>
+                <View className="cardShowAni" style={{ paddingTop: rpxToPx(26) }}>
 
-                <View className="content_card">
-                    <View style={{ display: 'flex', flexDirection: 'row' }} >
-                        <NewButton type={NewButtonType.custom}
-                            onClick={() => {
-                                setStep(0)
-                                setFocus(false)
-                            }}>
+                    <View className="content_card">
+                        <View style={{ display: 'flex', flexDirection: 'row' }} >
+                            <NewButton type={NewButtonType.custom}
+                                onClick={() => {
+                                    setStep(0)
+                                    setFocus(false)
+                                }}>
 
-                            <View className="sel_tag">
-                                {/* <View className="h34 bold">{selPostCount}</View>
+                                <View className="sel_tag">
+                                    {/* <View className="h34 bold">{selPostCount}</View>
                                 <View className="h34" style={{ marginLeft: rpxToPx(6) }}>次</View>
                                 <View style={{
                                     width: rpxToPx(2),
@@ -706,92 +707,93 @@ export default function LogRecord() {
                                     marginLeft: rpxToPx(12),
                                     marginRight: rpxToPx(12)
                                 }} /> */}
-                                <View className="h34 bold">{chooseTitle}</View>
-                                <View style={{ width: rpxToPx(6) }} />
-                                <IconArrow width={rpxToPx(34)} color='#000' />
+                                    <View className="h34 bold">{chooseTitle}</View>
+                                    <View style={{ width: rpxToPx(6) }} />
+                                    <IconArrow width={rpxToPx(34)} color='#000' />
 
-                            </View>
-                        </NewButton>
-                    </View>
-                    {/* <Input placeholder="hhhhhhh" style={{textAlign:'center'}}/> */}
+                                </View>
+                            </NewButton>
+                        </View>
+                        {/* <Input placeholder="hhhhhhh" style={{textAlign:'center'}}/> */}
 
-                    <Textarea placeholder={t('health.add_text')} className="textarea2 h44"
-                        placeholder-style="color:rgba(0,0,0,0.2)"
-                        value={desc}
-                        focus={focus}
-                        onBlur={() => {
-                            setFocus(false)
-                        }}
-                        onInput={e => {
-                            setDesc(e.detail.value)
-                        }} />
-                    <View className="form2">
-                        {
-                            pics.map((item, index) => {
-                                return <View className="cover" key={index}>
-                                    <Image src={item.url + scale} mode="aspectFill" className="cover" style={{
-                                        margin: 0,
-                                    }} key={index} onClick={() => {
-                                        Taro.previewImage({
-                                            current: pics[index].url,
-                                            urls: pics.map(file => file.url)
-                                        })
-                                    }} />
-                                    <View className="cover_del" onClick={() => {
-                                        showAlert({
-                                            title: t('health.del_title'),
-                                            content: '',
-                                            cancelText: t('health.del_cancel'),
-                                            confirmText: t('health.del_confirm'),
-                                            showCancel: true,
-                                            confirm: () => {
-                                                var array = JSON.parse(JSON.stringify(pics))
-                                                array.splice(index, 1)
-                                                setPics(array)
-                                            }
-                                        })
-                                    }}>
-                                        <View className="cover_del_btn">
-                                            <IconClose width={10} height={10} color="#fff" />
+                        <Textarea placeholder={t('health.add_text')} className="textarea2 h44"
+                            placeholder-style="color:rgba(0,0,0,0.2)"
+                            value={desc}
+                            focus={focus}
+                            onBlur={() => {
+                                setFocus(false)
+                            }}
+                            onInput={e => {
+                                setDesc(e.detail.value)
+                            }} />
+                        <View className="form2">
+                            {
+                                pics.map((item, index) => {
+                                    return <View className="cover" key={index}>
+                                        <Image src={item.url + scale} mode="aspectFill" className="cover" style={{
+                                            margin: 0,
+                                        }} key={index} onClick={() => {
+                                            Taro.previewImage({
+                                                current: pics[index].url,
+                                                urls: pics.map(file => file.url)
+                                            })
+                                        }} />
+                                        <View className="cover_del" onClick={() => {
+                                            showAlert({
+                                                title: t('health.del_title'),
+                                                content: '',
+                                                cancelText: t('health.del_cancel'),
+                                                confirmText: t('health.del_confirm'),
+                                                showCancel: true,
+                                                confirm: () => {
+                                                    var array = JSON.parse(JSON.stringify(pics))
+                                                    array.splice(index, 1)
+                                                    setPics(array)
+                                                }
+                                            })
+                                        }}>
+                                            <View className="cover_del_btn">
+                                                <IconClose width={10} height={10} color="#fff" />
+                                            </View>
                                         </View>
                                     </View>
-                                </View>
-                            })
-                        }
-                        {
-                            pics.length < 9 && <NewButton
-                                type={NewButtonType.custom}
-                                onClick={tapPic}>
-                                <View className="cover" style={{}}><IconCamera color="#000" width={rpxToPx(48)} /></View>
-                            </NewButton>
-                        }
+                                })
+                            }
+                            {
+                                pics.length < 9 && <NewButton
+                                    type={NewButtonType.custom}
+                                    onClick={tapPic}>
+                                    <View className="cover" style={{}}><IconCamera color="#000" width={rpxToPx(48)} /></View>
+                                </NewButton>
+                            }
+                        </View>
                     </View>
-                </View>
 
 
 
 
-                <View className="time_view" onClick={() => {
-                    setShowTimePicker(true)
-                }}>
-                    <View style={{ opacity: 0.25 }}>
-                        <IconClock width={rpxToPx(36)} color={MainColorType.black} />
-                    </View>
+                    <View className="time_view" onClick={() => {
+                        setShowTimePicker(true)
+                    }}>
 
-                    <View className="h30" style={{ opacity: 0.3, marginLeft: rpxToPx(12) }}>{t('health.time')}</View>
-                    <View style={{ flex: 1 }} />
-                    <View className="h30" style={{ opacity: 0.3 }}>{getDate() + time}</View>
-                    <IconArrow width={rpxToPx(34)} color={MainColorType.g02} />
-                    <View className="border_footer_line" style={{ left: rpxToPx(48) }} />
-                </View>
+                        <IconClock width={rpxToPx(36)} color={MainColorType.black_25} />
 
-                {
-                    router.params.join_id && <FollowInfo user={long.follow} />
-                }
 
+                        <View className="h30" style={{ opacity: 0.25, marginLeft: rpxToPx(12) }}>{t('health.time')}</View>
+                        <View style={{ flex: 1 }} />
+                        <View className="h30" style={{ opacity: 0.25 }}>{getDate() + time}</View>
+                        <IconArrow width={rpxToPx(34)} color={MainColorType.black_25} />
+                        <View className="border_footer_line" style={{ left: rpxToPx(48) }} />
+                    </View>
 
+                    {
+                        router.params.join_id && <FollowInfo user={long.follow} />
+                    }
 
-            </View>
+
+
+                </View>
+            </ScrollView>
         }
         {
             step == 2 && <View className="main_footer" style={{ backgroundColor: 'transparent' }}>

+ 68 - 6
src/_record/pages/time_record.scss

@@ -85,6 +85,67 @@
     width: 320px;
     border-radius: 28px;
     height: 172px;
+    position: relative;
+}
+
+.card_highlight {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    border-radius: 28px;
+}
+
+.start_card_show {
+    background-color: rgba($color: #ffffff, $alpha: 0.5);
+    animation: highlightShowAni 3s linear forwards;
+    opacity: 0;
+}
+
+.end_card_show{
+    background-color: rgba($color: #ffffff, $alpha: 0.25);
+    animation: highlightShowAni 3s  linear forwards;
+    opacity: 0;
+}
+
+.start_card_hide {
+    background-color: rgba($color: #ffffff, $alpha: 0.5);
+    animation: highlightHideAni 0.3s 0.1s linear forwards;
+    opacity: 1;
+}
+
+.end_card_hide {
+    background-color: rgba($color: #ffffff, $alpha: 0.25);
+    animation: highlightHideAni 0.3s 0.1s linear forwards;
+    opacity: 1;
+}
+
+@keyframes highlightShowAni {
+    0% {
+        opacity: 0;
+    }
+    10%{
+        opacity: 1;
+    }
+
+    90%{
+        opacity: 1;
+    }
+
+    100% {
+        opacity: 0;
+    }
+}
+
+@keyframes highlightHideAni {
+    0% {
+        opacity: 1;
+    }
+
+    100% {
+        opacity: 0;
+    }
 }
 
 .share_icon {
@@ -145,17 +206,17 @@
     }
 }
 
-.shareBtnAni{
+.shareBtnAni {
     opacity: 0;
     animation: showAni 0.1s 0.1s linear forwards;
 }
 
-.eatBtnAni{
+.eatBtnAni {
     opacity: 0;
     animation: showAni 0.1s 0.2s linear forwards;
 }
 
-.momentBtnAni{
+.momentBtnAni {
     opacity: 0;
     width: 646px;
     height: 96px;
@@ -168,16 +229,17 @@
     justify-content: center;
 }
 
-@keyframes showAni{
+@keyframes showAni {
     0% {
         opacity: 0;
     }
-    100%{
+
+    100% {
         opacity: 1;
     }
 }
 
-.share_btn1{
+.share_btn1 {
     display: flex;
     flex-direction: row;
     align-items: center;

+ 35 - 15
src/_record/pages/time_record.tsx

@@ -21,6 +21,9 @@ import showActionSheet from "@/components/basic/ActionSheet";
 import { useTranslation } from "react-i18next";
 import FollowInfo from "@/_moment/components/follow_info";
 
+import MomentDetailShare from "@/pages/moment/moment_detail_share";
+
+
 let timer
 let useRoute;
 let useNavigation;
@@ -94,10 +97,18 @@ export default function TimeRecord() {
             else {
                 path = 'pages/clock/Clock'
             }
+            var title = ''
+            var shareDate = global.language == 'en' ? 'Today\'s' : '今日'
+            if (scenario == 'FAST') {
+                title = t('health.share_check_in', { date: shareDate, type: t('health.fasting') })
+            }
+            else {
+                title = t('health.share_check_in', { date: shareDate, type: t('health.sleep') })
+            }
             return {
-                title: '分享标题',
+                title: title,
                 path: path,
-                imageUrl: shareUrl
+                imageUrl: global.momentdetail_share_url//shareUrl
             }
         })
     }
@@ -441,20 +452,21 @@ export default function TimeRecord() {
                                         <View className="operate_item" >
                                             <View className="g02 h24 white_50">{scenario == 'FAST' ? t('health.started') : t('health.bedtime1')}</View>
                                             <View className="h44 bold white" style={{ marginTop: rpxToPx(8), marginBottom: rpxToPx(8) }}>{TimeFormatter.dateTimeFormate(info.time.start_timestamp, true)}</View>
-                                            <View className="h30 bold white_50" style={{ color: MainColorType.white }}>{scenario == 'FAST' ? t('health.adjust_start') : t('health.adjust_bedtime')}</View>
+                                            <View className="h30 bold white_50">{scenario == 'FAST' ? t('health.adjust_start') : t('health.adjust_bedtime')}</View>
                                         </View>
                                     </NewButton>
                                     <NewButton type={NewButtonType.custom} onClick={() => {
                                         setShowEndDatePicker(true)
                                     }}>
-                                        <View className="operate_item" style={{ backgroundColor: showHighlight ? '#ffffff80' : 'transparent' }} >
+                                        <View className="operate_item" >
+                                            <View className={showHighlight ? 'card_highlight end_card_show' : ''} />
                                             <View className="g02 h24 white_50">{scenario == 'FAST' ? t('health.finished') : t('health.wokeup')}</View>
                                             <View className="h44 bold white" style={{ marginTop: rpxToPx(8), marginBottom: rpxToPx(8) }}>{TimeFormatter.dateTimeFormate(info.time.end_timestamp, true)}</View>
-                                            <View className="h30 bold white_50" style={{ color: MainColorType.white }}>{scenario == 'FAST' ? t('health.adjust_end') : t('health.adjust_wake_up')}</View>
+                                            <View className="h30 bold white_50">{scenario == 'FAST' ? t('health.adjust_end') : t('health.adjust_wake_up')}</View>
                                         </View>
                                     </NewButton>
                                 </View> :
-                                    <View className="white bold" style={{ fontSize: rpxToPx(72), display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }}>{scenario == 'FAST' ?t('health.fast_finished'):t('health.sleep_finished')}</View>
+                                    <View className="white bold" style={{ fontSize: rpxToPx(72), display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }}>{scenario == 'FAST' ? t('health.fast_finished') : t('health.sleep_finished')}</View>
                             }
 
 
@@ -494,7 +506,7 @@ export default function TimeRecord() {
                         })
                     }}><View
 
-                        className="h34 bold white_75 eatBtnAni" style={{
+                        className="h30 bold white_75 eatBtnAni" style={{
                             backgroundColor: MainColorType.black_05,
                             marginTop: rpxToPx(26),
                             width: rpxToPx(698),
@@ -590,7 +602,8 @@ export default function TimeRecord() {
                         <NewButton type={NewButtonType.custom} onClick={() => {
                             setShowDatePicker(true)
                         }}>
-                            <View className="operate_item" style={{ backgroundColor: showHighlight ? '#ffffff80' : 'transparent' }}>
+                            <View className="operate_item">
+                                <View className={showHighlight ? 'card_highlight start_card_show' : ''} />
                                 <View className="black_50 h24">{scenario == 'FAST' ? t('health.started') : t('health.bedtime1')}</View>
                                 <View className="h44 bold" style={{ marginTop: rpxToPx(8), marginBottom: rpxToPx(8) }}>{TimeFormatter.abbrTimestampFormat(info.time.start_timestamp)}</View>
                                 <View className="h30 bold" style={{ color: MainColorType.orange }}>{scenario == 'FAST' ? t('health.adjust_start') : t('health.adjust_bedtime')}</View>
@@ -646,13 +659,15 @@ export default function TimeRecord() {
                 }
                 {
                     status == 'OG' && <View className="share_icon">
-                        <Image onClick={() => {
-                            setShareUrl('')
-                            setShowShare(true)
-                        }} src={require('@assets/_health/wechat.png')} style={{
-                            width: rpxToPx(72),
-                            height: rpxToPx(72)
-                        }} />
+                        <ShareBtn>
+                            <Image onClick={() => {
+                                // setShareUrl('')
+                                // setShowShare(true)
+                            }} src={require('@assets/_health/wechat.png')} style={{
+                                width: rpxToPx(72),
+                                height: rpxToPx(72)
+                            }} />
+                        </ShareBtn>
                     </View>
                 }
 
@@ -853,5 +868,10 @@ export default function TimeRecord() {
                 }}
             />
         }
+
+        <MomentDetailShare
+            user={user}
+            canvas_id="time_record"
+            btnColor={MainColorType.orange} />
     </View>
 }

+ 6 - 6
src/context/locales/en.js

@@ -1285,12 +1285,12 @@ export default {
         wokeup:'WOKE UP',
         discard: 'Discard',
         discard_restart: 'Discard and Restart',
-        adjust_fast_goal:'Adjust Fast goal',
-        adjust_fast_start_time:'Adjust Fasting Start Time',
-        adjust_fast_end_time:'Adjust Fasting End Time',
-        adjust_sleep_goal:'Adjust Sleep Goal',
-        adjust_bed_time:'Adjust Bedtime',
-        adjust_wake_up:'Adjust Wake Up',
+        adjust_fast_goal:'Fast Goal',
+        adjust_fast_start_time:'Start Time',
+        adjust_fast_end_time:'End Time',
+        adjust_sleep_goal:'Sleep Goal',
+        adjust_bed_time:'Bedtime',
+        adjust_wake_up:'Wake Up',
         elapsed:'ELAPSED {{percent}}',
         view_in_moments:'View in Moments',
         what_eating:'What\'re you eating?',

+ 11 - 11
src/context/locales/zh.js

@@ -1274,25 +1274,25 @@ export default {
         fast_finished: '断食已完成',
         sleep_finished: '睡眠已完成',
 
-        started: '开始',
+        started: '开始时间',
         time_goal: '{{time}}目标',
-        finished: '结束',
+        finished: '结束时间',
         adjust_goal: '调整目标',
         adjust_start: '调整开始',
         adjust_end: '调整结束',
         adjust_bedtime: '调整就寝',
         adjust_wake_up: '调整起床',
-        bedtime1:'就寝',
-        wokeup:'起床',
+        bedtime1:'就寝时间',
+        wokeup:'起床时间',
         discard: '放弃',
         discard_restart: '放弃并重新开始',
-        adjust_fast_goal:'调整断食目标',
-        adjust_fast_start_time:'调整断食开始时间',
-        adjust_fast_end_time:'调整断食结束时间',
-        adjust_sleep_goal:'调整睡眠目标',
-        adjust_bed_time:'调整就寝时间',
-        adjust_wake_up:'调整起床时间',
-        elapsed:'时间已过 {{percent}}',
+        adjust_fast_goal:'断食目标',
+        adjust_fast_start_time:'开始时间',
+        adjust_fast_end_time:'结束时间',
+        adjust_sleep_goal:'睡眠目标',
+        adjust_bed_time:'就寝时间',
+        adjust_wake_up:'起床时间',
+        elapsed:'进度 {{percent}}',
 
         view_in_moments:'去搭子圈查看',
         what_eating:'吃点什么?',

+ 1 - 0
src/features/health/HistoryItem.tsx

@@ -337,6 +337,7 @@ export default function HistoryItem(props: {
                         color={getThemeColor(item.window)}
                         showRing={props.fast_type != 'LF'}
                         desc={item.description}
+                        time_desc={item.time_desc}
                         icon={
                             props.fast_type == 'LF' ? <IconLongFast color={MainColorType.fast} width={rpxToPx(32)} /> : null
                         }

+ 1 - 0
src/pages/account/Journal.tsx

@@ -346,6 +346,7 @@ export default function Journal() {
                             color={getThemeColor(temp.window)}
                             showRing={true}
                             desc={temp.description}
+                            time_desc={temp.time_desc}
                             icon={
                                 null
                             }

+ 1 - 0
src/pages/account/JournalDetail.tsx

@@ -323,6 +323,7 @@ export default function JournalDetail() {
                             color={getThemeColor(item.window)}
                             showRing={true}
                             desc={item.description}
+                            time_desc={item.time_desc}
                             icon={
                                 null
                             }

+ 1 - 1
src/pages/clock/ClockIndex.scss

@@ -15,7 +15,7 @@
     background-color: rgba($color: #ffffff, $alpha: 0.25);
     width: 320px;
     height: 260px;
-    border-radius: 24px;
+    border-radius: 42px;
     margin-bottom: 30px;
     display: flex;
     flex-direction: column;

+ 7 - 14
src/pages/clock/ClockIndex.tsx

@@ -174,20 +174,11 @@ export default function ClockIndex() {
 
     if (!loaded) return <View />
 
-    return <ScrollView style={{ height: '100vh' }} scrollY><View style={{ position: 'relative', minHeight: '101vh' }}>
+    return <View><ScrollView style={{ height: '100vh' }} scrollY><View style={{ position: 'relative' }}>
         <View className="main_bg" style={{ background: getBackground() }} />
-        <View
-            onClick={() => {
-                if (!user.isLogin) {
-                    jumpPage('/_account/pages/ChooseAuth')
-                    return
-                }
-                // jumpPage('/_record/pages/time_record')
-            }}
-            style={{ height: 100, width: 100, opacity: 0 }}>demo</View>
-        <View className="h60 bold" style={{ marginLeft: rpxToPx(52) }}>{record.time ? record.time.greeting : ''}</View>
+        <View className="h60 bold" style={{ marginLeft: rpxToPx(52), marginTop: rpxToPx(212) }}>{record.time ? record.time.greeting : ''}</View>
         <View style={{ display: 'flex', flexDirection: 'row' }}>
-            <View className="h44 bold" style={{ marginLeft: rpxToPx(52), marginTop: rpxToPx(66), marginBottom: rpxToPx(58), position: 'relative', paddingBottom: rpxToPx(26) }}>{t('health.check_in')}
+            <View className="h44 bold" style={{ marginLeft: rpxToPx(52), marginTop: rpxToPx(66), marginBottom: rpxToPx(32), position: 'relative', paddingBottom: rpxToPx(20) }}>{t('health.check_in')}
                 <View className="tab_border_line" />
             </View>
         </View>
@@ -233,8 +224,10 @@ export default function ClockIndex() {
             />
         }
 
+    </View>
+    </ScrollView>
         {
             process.env.TARO_ENV == 'weapp' && <TabBar index={0} />
-        }</View>
-    </ScrollView>
+        }
+    </View>
 }

+ 2 - 1
src/pages/moment/moment_detail_share.tsx

@@ -2,6 +2,7 @@ import { useDispatch, useSelector } from "react-redux";
 import { useEffect, useState } from "react";
 import { View, Canvas } from "@tarojs/components";
 import Taro, { useDidShow } from "@tarojs/taro";
+import { MainColorType } from "@/context/themes/color";
 
 export default function MomentDetailShare(props: { user: any, canvas_id?: string, cover?: string, btnColor?: string }) {
     const user = props.user;
@@ -133,7 +134,7 @@ export default function MomentDetailShare(props: { user: any, canvas_id?: string
                 ctx.arcTo(x, y + height, x, y, radius); // 左下角
                 ctx.arcTo(x, y, x + width, y, radius); // 左上角
                 ctx.closePath();
-                ctx.fillStyle = props.btnColor ? props.btnColor : '#ff0000'; // 设置填充颜色为红色
+                ctx.fillStyle = MainColorType.orange//props.btnColor ? props.btnColor : '#ff0000'; // 设置填充颜色为红色
                 ctx.fill(); // 填充矩形
 
                 ctx.font = `bold ${26 * dpr}px sans-serif`

+ 26 - 3
src/pages/moment/moment_item.tsx

@@ -16,11 +16,12 @@ import { IconActive, IconShare } from "@/components/basic/Icons";
 import Taro from "@tarojs/taro";
 import LongCard from "@/_moment/components/long_card";
 import NewButton, { NewButtonType } from "@/_health/base/new_button";
-import { useSelector } from "react-redux";
+import { useDispatch, useSelector } from "react-redux";
 import showActionSheet from "@/components/basic/ActionSheet";
 import { useTranslation } from "react-i18next";
 import showAlert from "@/components/basic/Alert";
 import { delEvents } from "@/services/health";
+import { setFollow, setJoinData } from "@/store/long";
 
 dayjs.extend(relativeTime);
 dayjs.extend(isToday);
@@ -34,6 +35,7 @@ export default function MomentItem(props: { data: any, del?: any }) {
     const my = useSelector((state: any) => state.user);
     const { link, moment, user, join } = props.data
     const { t } = useTranslation()
+    const dispatch = useDispatch()
 
     const formatImages = (list) => {
         return list.map(obj => obj.url);
@@ -174,6 +176,7 @@ export default function MomentItem(props: { data: any, del?: any }) {
                     color={getThemeColor(link.window)}
                     showRing={true}
                     desc={link.ring.description}
+                    time_desc={link.ring.time_desc}
                     og={link.status == 'OG'}
                     startTimestamp={link.ring.start_timestamp}
                     endTimerstamp={link.ring.end_timestamp ?? new Date().getTime()}
@@ -211,10 +214,30 @@ export default function MomentItem(props: { data: any, del?: any }) {
                     onClick={tapMore}
                 />
                         } */}
-                <NewButton type={NewButtonType.custom} onClick={tapShare}>
+                {
+                    join && join.status == 'JOIN' && <NewButton type={NewButtonType.custom} onClick={() => {
+                        if (!my.isLogin) {
+                            jumpPage('/_account/pages/ChooseAuth')
+                            return
+                        }
+                        dispatch(setFollow(user))
+                        dispatch(setJoinData(join))
+                        if (join.window == 'ACTIVE' || join.window == 'EAT') {
+                            jumpPage(`/_record/pages/log_record?scenario=${join.window == 'EAT' ? 'MEAL' : 'ACTIVITY'}&join_id=${join.key}`)
+                        }
+                        else if (join.window == 'FAST' || join.window == 'SLEEP') {
+                            jumpPage(`/_record/pages/time_record?scenario=${join.window}&join_id=${join.key}`)
+                        }
+
+                        // jumpPage(`/_moment/pages/long_detail?join_id=${join.key}&window=${join.window}&status=${join.status}`)
+                    }}>
+                        <View className="h24" style={{ color: MainColorType.link, padding: rpxToPx(13) }}>跟卡</View>
+                    </NewButton>
+                }
+                <NewButton btnStyle={{ paddingLeft: rpxToPx(20), paddingRight: rpxToPx(20) }} type={NewButtonType.custom} onClick={tapShare}>
                     <IconShare color={MainColorType.link + 'cc'} width={20} />
                 </NewButton>
-                {my.isLogin && my.id == user.id && <View style={{width:rpxToPx(16)}}/>}
+                {my.isLogin && my.id == user.id && <View style={{ width: rpxToPx(16) }} />}
                 {
                     my.isLogin && my.id == user.id && <NewButton
                         type={NewButtonType.more}

+ 34 - 12
src/pages/moment/moment_main.tsx

@@ -83,6 +83,7 @@ export default function MomentMain() {
     const [endSignal, setEndSignal] = useState(0)
 
     const [closeGuide, setCloseGuide] = useState(false)
+    const [showGuide,setShowGuide] = useState(false)
     const [showShareGuide, setShowShareGuide] = useState(false)
     const [shareInfo, setShareInfo] = useState<any>(null)
     const query = Taro.createSelectorQuery()
@@ -90,6 +91,8 @@ export default function MomentMain() {
     const dispatch = useDispatch()
     const { t } = useTranslation()
 
+    const momentsRef = useRef(moments)
+
     useEffect(() => {
 
         dayjs.locale(global.language == 'en' ? 'en' : 'zh-cn');
@@ -121,6 +124,10 @@ export default function MomentMain() {
 
     }, [])
 
+    useEffect(() => {
+        momentsRef.current = moments;
+    }, [moments])
+
     function listenFollowUser(e) {
         myFriends()
     }
@@ -133,12 +140,21 @@ export default function MomentMain() {
         myFriends()
     }
 
-    function refreshItem(e){
+    function refreshItem(e) {
         if (!e) return
-        var list = JSON.parse(JSON.stringify(moments))
-        list.map((item)=>{
-            if (item.id == e.id){
-                return e
+        const { link, moment, user } = e
+        var list = JSON.parse(JSON.stringify(momentsRef.current))
+        list.map((item) => {
+            if (item.link.event_id == link.event_id) {
+                if (link) {
+                    item.link = e.link
+                }
+                if (moment) {
+                    item.moment = e.moment
+                }
+                if (user) {
+                    item.user = e.user
+                }
             }
         })
         setMoments(list)
@@ -373,7 +389,8 @@ export default function MomentMain() {
                     display: 'flex', alignItems: 'center', justifyContent: 'center'
                 }}
                     onClick={() => {
-                        setCloseGuide(true)
+                        // setCloseGuide(true)
+                        setShowGuide(false)
                     }}
                 >
                     <IconClose color="#000" width={30} height={30} />
@@ -458,9 +475,11 @@ export default function MomentMain() {
                     <View onClick={more} style={{ position: 'absolute', left: 10, top: 0, bottom: 0, width: 44, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                         <IconMenu color="#000" width={rpxToPx(40)} />
                     </View>
-                    <View style={{ position: 'absolute', left: 54, top: 0, bottom: 0, width: 44, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
+                    <View onClick={()=>{
+                        setShowGuide(true)
+                    }} style={{ position: 'absolute', left: 54, top: 0, bottom: 0, width: 44, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                         <Image src={require('@assets/_health/wechat.png')} style={{ width: rpxToPx(48), height: rpxToPx(48) }} />
-                        <Button openType="share" style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, opacity: 0 }} />
+                        {/* <Button openType="share" style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, opacity: 0 }} /> */}
                     </View>
                 </View>
             </View>
@@ -518,12 +537,12 @@ export default function MomentMain() {
                             }
                             return <View key={index} id={`history2-${index}`}>
                                 <MomentItem data={item} del={
-                                    ()=>{
+                                    () => {
                                         var list = JSON.parse(JSON.stringify(moments))
-                                        list.splice(index,1)
+                                        list.splice(index, 1)
                                         setMoments(list)
                                     }
-                                }/>
+                                } />
                             </View>
                         })
                     }
@@ -549,8 +568,11 @@ export default function MomentMain() {
             {
                 process.env.TARO_ENV == 'weapp' && <TabBar index={4} />
             }
-            {
+            {/* {
                 homeType == 'NO_FRIEND' && !closeGuide && friendGuide()
+            } */}
+            {
+                showGuide && friendGuide()
             }
             {
                 homeType == 'NO_MOMENT' && !closeGuide && empty()