leon 1 anno fa
parent
commit
b2b3be047c

+ 0 - 0
src/_health/base/demo_cell.js


+ 81 - 0
src/_health/base/new_durationpicker.tsx

@@ -0,0 +1,81 @@
+import { rpxToPx } from "@/utils/tools";
+import { PickerView, PickerViewColumn, Text, View } from "@tarojs/components";
+import { useEffect, useState } from "react";
+import './new_timepicker.scss'
+import dayjs from "dayjs";
+import { MainColorType } from "@/context/themes/color";
+
+export default function NewDurationPicker(props: { value?: any, onChange?: any, color?: string }) {
+    const [items, setItems] = useState<any>([[0]])
+    const [values, setValues] = useState<any>([0])
+    const [loaded, setLoaded] = useState(false)
+    useEffect(() => {
+        var hours: any = []
+        var tempValues: any = [0]
+
+        var array:any = []
+        for (var i=0;i<=12*3;i++){
+            var count = i*5;
+            var hour = Math.floor(count/60);
+            var minute = count%60;
+            var str = ''
+            if (hour>0){
+                str = hour+'小时'
+            }
+            if (minute>0){
+                str += minute+'分钟'
+            }
+            if (hour==0 && minute==0){
+                str = '0分钟'
+            }
+            array.push(str)
+        }
+        setItems([array])
+        setValues(tempValues)
+        setLoaded(true)
+    }, [])
+
+    function onPickerChange(e) {
+        setValues(e.detail.value)
+        if (props.onChange) {
+            var list = e.detail.value
+            props.onChange((list[0] + '').padStart(2, '0') + ':' + (list[1] + '').padStart(2, '0'))
+        }
+    }
+
+    function getColor(i, j) {
+        if (i == 0 && j == values[0]) {
+            return true
+        }
+        if (i == 1 && j == values[1]) {
+            return true
+        }
+        return false
+    }
+    if (!loaded) return <View />
+
+    const bgStyle = `background-color: ${props.color}1A !important;`
+    return <PickerView
+        value={values}
+        style={{ color: '#000', height: rpxToPx(340), width: rpxToPx(670) }}
+        onChange={onPickerChange}
+        indicatorClass="pick_sel_item"
+        indicatorStyle={bgStyle}//""
+        immediateChange={true}
+        className="picker"
+
+    >
+        {
+            items.map((item, index) => {
+                return <PickerViewColumn key={index}>
+                    {item.map((obj, j) => {
+                        return (
+                            <Text key={j} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: getColor(index, j) ? props.color ?? MainColorType.fast : '#000' }}>{obj}</Text>
+                        );
+                    })}
+                </PickerViewColumn>
+            })
+        }
+
+    </PickerView >
+}

+ 20 - 4
src/_health/base/new_modal.scss

@@ -13,7 +13,7 @@
     animation: modalBgAnim 0.2s linear forwards;
 }
 
-.rn_modal{
+.rn_modal {
     position: fixed;
     top: -2px;
     left: 0;
@@ -114,7 +114,7 @@
     overflow: hidden;
     display: flex;
     flex-direction: column;
-    background-color: rgba(0,0,0,0.95);
+    background-color: rgba(0, 0, 0, 0.95);
     // background-color: rgba($color: #000000, $alpha: 0);
     // animation: modalBgAnim 0.2s linear forwards;
 }
@@ -152,8 +152,24 @@
     position: relative;
 }
 
-.modal_footer{
-    
+.modal_footer {
+    padding-bottom: 50px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+}
+
+.modal_footer_btn {
+    width: 670px;
+    height: 96px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+    border-radius: 24px;
+    font-size: 30px;
+    font-weight: bold;
 }
 
 .modal_operate {

+ 10 - 2
src/_health/base/new_modal.tsx

@@ -4,6 +4,7 @@ import React, { useEffect, useRef, useState } from 'react';
 import { ModalType } from '@/utils/types';
 import Taro from '@tarojs/taro';
 import { vibrate } from '@/utils/tools';
+import { MainColorType } from '@/context/themes/color';
 
 
 let ModalRN, Animated
@@ -16,6 +17,7 @@ if (process.env.TARO_ENV == 'rn') {
 export default function NewModal(props: {
     children: React.ReactNode,
     title?: string,
+    btnTitle?: string,
     dismiss: Function,
     confirm?: Function,
     themeColor?: string,
@@ -100,7 +102,7 @@ export default function NewModal(props: {
         // animationType="slide"
         // style={{backgroundColor:'red'}}
         >
-            <View style={{ flex: 1, backgroundColor: props.themeIsWhite?'#ffffff90':'#000000cc' }}>
+            <View style={{ flex: 1, backgroundColor: props.themeIsWhite ? '#ffffff90' : '#000000cc' }}>
                 <View style={{ flex: 1, backgroundColor: 'transparent' }} onClick={(e) => {
                     rndismiss()
                 }}></View>
@@ -128,7 +130,13 @@ export default function NewModal(props: {
             {
                 props.children
             }
-            <View className='modal_footer'></View>
+            <View className='modal_footer'>
+                <View className='modal_footer_btn'
+                    onClick={() => {
+                        props.confirm && props.confirm()
+                    }}
+                    style={{ backgroundColor: props.themeColor ?? MainColorType.fast }}>{props.btnTitle ?? '确定'}</View>
+            </View>
 
         </View>
 

+ 10 - 6
src/_health/base/new_timepicker.tsx

@@ -1,13 +1,14 @@
 import { rpxToPx } from "@/utils/tools";
-import { PickerView, PickerViewColumn, Text,View } from "@tarojs/components";
+import { PickerView, PickerViewColumn, Text, View } from "@tarojs/components";
 import { useEffect, useState } from "react";
 import './new_timepicker.scss'
 import dayjs from "dayjs";
+import { MainColorType } from "@/context/themes/color";
 
-export default function NewTimePicker(props: { time?: string, onChange?: any }) {
+export default function NewTimePicker(props: { time?: string, onChange?: any, color?: string }) {
     const [items, setItems] = useState<any>([[0], [0]])
     const [values, setValues] = useState<any>([0, 0])
-    const [loaded,setLoaded] = useState(false)
+    const [loaded, setLoaded] = useState(false)
     useEffect(() => {
         var hours: any = []
         var tempValues: any = [0, 0]
@@ -37,7 +38,8 @@ export default function NewTimePicker(props: { time?: string, onChange?: any })
     function onPickerChange(e) {
         setValues(e.detail.value)
         if (props.onChange) {
-            props.onChange(e.detail.value)
+            var list = e.detail.value
+            props.onChange((list[0] + '').padStart(2, '0') + ':' + (list[1] + '').padStart(2, '0'))
         }
     }
 
@@ -51,13 +53,15 @@ export default function NewTimePicker(props: { time?: string, onChange?: any })
         return false
     }
     if (!loaded) return <View />
+
+    const bgStyle = `background-color: ${props.color}1A !important;`
     return <PickerView
         value={values}
         // itemStyle={{ color: '#000' }}
         style={{ color: '#000', height: rpxToPx(340), width: rpxToPx(670) }}
         onChange={onPickerChange}
         indicatorClass="pick_sel_item"
-        indicatorStyle="background-color: #FF2E661A !important;"
+        indicatorStyle={bgStyle}//""
         immediateChange={true}
         className="picker"
     // maskClass={props.hideTitle?"picker-mask-small":"picker-mask"}
@@ -67,7 +71,7 @@ export default function NewTimePicker(props: { time?: string, onChange?: any })
                 return <PickerViewColumn key={index}>
                     {item.map((obj, j) => {
                         return (
-                            <Text key={j} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: getColor(index, j) ? '#FF2E66' : '#000' }}>{obj}</Text>
+                            <Text key={j} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: getColor(index, j) ? props.color ?? MainColorType.fast : '#000' }}>{obj}</Text>
                         );
                     })}
                 </PickerViewColumn>

+ 1 - 1
src/_health/components/add_label.tsx

@@ -159,7 +159,7 @@ export default function AddLabel(props: { labels: any, defaultValue?: string, di
                         <Text>Picker placeholder</Text> */}
                         <NewTimePicker onChange={e=>{
                             console.log(e)
-                            setStrTime((e[0]+'').padStart(2,'0')+':'+(e[1]+'').padStart(2,'0'))
+                            setStrTime(e)
                         }}/>
                     </View>
             }

+ 40 - 0
src/_health/components/post_moment_time.scss

@@ -0,0 +1,40 @@
+.picker_time_card {
+    background-color: #fff;
+    border-radius: 32px;
+    overflow: hidden;
+    width: 670px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+
+.picker_time_card_header {
+    width: 670px;
+    height: 128px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: row;
+    position: relative;
+}
+
+.picker_time_card_footer {
+    width: 670px;
+    height: 128px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: row;
+    position: relative;
+}
+
+.time_btn {
+    width: 196px;
+    height: 84px;
+    border-radius: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background-color: #B2B2B21A;
+    color: #000;
+}

+ 98 - 0
src/_health/components/post_moment_time.tsx

@@ -0,0 +1,98 @@
+import { View, Text, Image } from '@tarojs/components'
+import './post_moment_time.scss'
+import NewModal from '../base/new_modal'
+import { useState } from 'react'
+import { useSelector } from 'react-redux';
+import { getThemeColor } from '@/features/health/hooks/health_hooks';
+import { rpxToPx } from '@/utils/tools';
+import NewTimePicker from '../base/new_timepicker';
+import { IconCalendar, IconTarget } from '@/components/basic/Icons';
+import NewDurationPicker from '../base/new_durationpicker';
+
+export default function PostMomentTime(props: {
+    title?: string,
+    time: string,
+    onChange: any, dismiss: any
+}) {
+    const health = useSelector((state: any) => state.health);
+    const [showDurationPicker, setShowDurationPicker] = useState(false)
+    const [isYesterday, setIsYesterday] = useState(false)
+    const [showMore, setShowMore] = useState(false)
+    const [time, setTime] = useState(props.time)
+
+    function durationContent() {
+        return <View className='picker_time_card'>
+            <View className='picker_time_card_header'>
+                <Text>Duration</Text>
+                <View className='time_btn' onClick={() => setShowDurationPicker(true)}>30 mins</View>
+            </View>
+            {
+                showDurationPicker && <NewDurationPicker />
+            }
+            
+            <View className='picker_time_card_footer'>
+                <IconTarget width={rpxToPx(24)} color='#5C7099' />
+                <Text style={{ color: '#5C7099', marginLeft: rpxToPx(12), fontSize: rpxToPx(26) }}>Scheduled for xxx today</Text>
+
+            </View>
+        </View>
+    }
+    return <NewModal
+        title='开始时间'
+        dismiss={props.dismiss}
+        confirm={() => {
+            props.onChange(time)
+        }}
+        themeColor={getThemeColor(health.mode)}>
+        <View style={{ flexDirection: 'column', display: 'flex', alignItems: 'center' }}>
+
+            <View className='picker_time_card'>
+                <View className='picker_time_card_header'>
+                    <View style={{ flex: 1 }} />
+                    <View className='time_btn'>Yesterday</View>
+                    <View style={{ width: rpxToPx(12) }} />
+                    <View className='time_btn' onClick={()=>{
+                        setShowDurationPicker(false)
+                    }}>{time}</View>
+                    <View style={{ flex: 1 }} />
+                    {
+                        !showDurationPicker && <View className='border_footer_line' />
+                    }
+                </View>
+                {
+                    !showDurationPicker && <NewTimePicker time={time} onChange={(e) => {
+                        setTime(e)
+                    }} color={getThemeColor(health.mode)} />
+                }
+                {
+                    !showDurationPicker && <View className='picker_time_card_footer'>
+                        <IconCalendar width={rpxToPx(24)} color='#5C7099' />
+                        <Text style={{ color: '#5C7099', marginLeft: rpxToPx(12), fontSize: rpxToPx(26) }}>Scheduled for xxx today</Text>
+                    </View>
+                }
+
+            </View>
+            <View style={{ marginBottom: rpxToPx(72), marginTop: rpxToPx(36) }}>
+                {
+                    showMore ? durationContent() :
+                        <View
+                            onClick={() => setShowMore(true)}
+                            style={{
+                                flexDirection: 'row',
+                                width: rpxToPx(142),
+                                height: rpxToPx(72),
+                                display: 'flex',
+                                alignItems: 'center',
+                                justifyContent: 'center'
+                            }}>
+                            <Image style={{ width: rpxToPx(26), height: rpxToPx(26) }} src={require('@assets/_health/setting.png')} />
+                            <Text style={{ color: '#5C7099', marginLeft: rpxToPx(10) }}>More</Text>
+                        </View>
+                }
+
+            </View>
+
+        </View>
+    </NewModal>
+
+}

+ 46 - 78
src/_health/pages/add_moment.tsx

@@ -16,6 +16,8 @@ import { useDispatch, useSelector } from "react-redux";
 import { getThemeColor } from "@/features/health/hooks/health_hooks";
 import { setShowActionTip } from "@/store/health";
 import DurationPicker from "../components/duration_picker";
+import NewModal from "../base/new_modal";
+import PostMomentTime from "../components/post_moment_time";
 
 
 let useRoute;
@@ -28,7 +30,6 @@ if (process.env.TARO_ENV == 'rn') {
 
 export default function AddMoment() {
     const [desc, setDesc] = useState('')
-    const [title, setTitle] = useState('')
     const { t } = useTranslation()
     const [imgUrl, setImgUrl] = useState('')
     const [startTime, setStartTime] = useState(0)
@@ -38,6 +39,9 @@ export default function AddMoment() {
     const [durationT, setDurationT] = useState(0)
     const dispatch = useDispatch()
     const health = useSelector((state: any) => state.health);
+    const [timestamp, setTimestamp] = useState(new Date().getTime())
+    const [showTimePicker, setShowTimePicker] = useState(false)
+    const [showTitlePicker, setShowTitlePicker] = useState(false)
 
 
 
@@ -54,47 +58,19 @@ export default function AddMoment() {
         router = useRouter()
     }
 
-    const [moment, setMoment] = useState(JSON.parse(router.params.moment))
+    const [time, setTime] = useState(dayjs().format('HH:mm'))
+    const [title, setTitle] = useState(router.params.title)
+
+    const { event_id, is_temp, schedule_id } = router.params
+
 
     useEffect(() => {
         global.set_time = new Date().getTime()
-
-        var obj = JSON.parse(router.params.moment)
-        if (obj.target) {
-            obj.target.timestamp = new Date().getTime()
-            setDurationT(obj.target.duration ?? 0)
+        if (is_temp && title == '') {
+            setShowTimePicker(true)
         }
-
-        setMoment(obj)
-
-
-        // var obj = JSON.parse(router.params.moment)
-        // var start = dayjs(obj.target.timestamp).format('HH:mm')
-        // setStartTime(start)
-        // setEndTime(obj.target_end_time)
     }, [])
 
-    function getIntervalHoursAndMinutes(time1, time2) {
-        // 将时间字符串转换为 Date 对象
-        const date1 = new Date(`2000-01-01T${time1}Z`);
-        const date2 = new Date(`2000-01-02T${time2}Z`);
-
-        // 计算两个 Date 对象之间的时间差
-        let intervalMs = Math.abs(date2.getTime() - date1.getTime());
-
-        // 如果 time2 比 time1 小, 说明跨天了, 需要加上一天的毫秒数
-        if (date2 < date1) {
-            intervalMs += 24 * 60 * 60 * 1000;
-        }
-
-        // 计算小时和分钟差
-        const intervalSeconds = Math.floor(intervalMs / 1000);
-        const hours = Math.floor(intervalSeconds / 3600);
-        const minutes = Math.floor((intervalSeconds % 3600) / 60);
-
-        return { hours, minutes };
-    }
-
     function duration() {
         const seconds = durationT / 1000
         var hours = Math.floor(seconds / 3600)
@@ -104,11 +80,9 @@ export default function AddMoment() {
         if (hours > 0) {
             time = hours + '小时'
         }
-        console.log(time)
         if (minutes > 0) {
             time += minutes + '分钟'
         }
-        console.log(time)
         return time
     }
 
@@ -144,29 +118,15 @@ export default function AddMoment() {
             return
         }
         var params: any = {
-            schedule_id: moment.schedule_id,
-            title: moment.title,
+            schedule_id: schedule_id,
+            title: title,
             description: desc,
-        }
-
-        if (moment.target) {
-            params.start = {
-                date: dayjs(moment.target.timestamp).format('YYYYMMDD'),
-                timestamp: moment.target.timestamp
-            }
-        }
-        else {
-            params.start = {
-                date: dayjs().format('YYYYMMDD'),
-                timestamp: new Date().getTime()
+            start: {
+                date: dayjs(timestamp).format('YYYYMMDD'),
+                timestamp: timestamp
             }
         }
 
-        if (title.length > 0) {
-            params.title = title
-        }
-
-
 
         if (imgUrl.length > 0) {
             params.media = [{
@@ -175,12 +135,12 @@ export default function AddMoment() {
                 source: 'album'
             }]
         }
-        if (moment.event_id) {
-            params.event_id = moment.event_id
-        }
-        if (moment.target && moment.target.duration) {
-            params.duration = durationT//moment.target.duration
+        if (event_id) {
+            params.event_id = event_id
         }
+        // if (moment.target && moment.target.duration) {
+        //     params.duration = durationT//moment.target.duration
+        // }
 
         params.extra = {
             set_time: global.set_time ? global.set_time : new Date().getTime(),
@@ -284,11 +244,9 @@ export default function AddMoment() {
     }
 
     function pickerContent() {
-        const timestamp = moment.target.timestamp
-        const strTime = dayjs(timestamp).format('HH:mm')
-        return <TimePicker time={strTime}
+        return <TimePicker time={time}
             color={MainColorType.eat}
-            title={moment.title}
+            title={title}
             confirm={(e) => {
                 confirmPickerTime(e)
             }}
@@ -304,15 +262,7 @@ export default function AddMoment() {
         date.setMinutes(list[1])
 
         console.log(date)
-
-        // const duration = meal.target_end_time-meal.target_start_time
-        // const endDate = date.getTime()+duration;
-        var data = JSON.parse(JSON.stringify(moment))
-        data.target.timestamp = date.getTime()
-        // data.schedule_end_time = dayjs(endDate).format('HH:mm')
-        // data.target_starts_time = date.getTime()
-        // data.target_end_time = date.getTime()+duration
-        setMoment(data)
+        setTimestamp(date.getTime())
         setShowPicker(false)
     }
 
@@ -322,7 +272,7 @@ export default function AddMoment() {
 
 
     return <View>
-        {
+        {/* {
             health.mode != 'FAST' && health.mode != 'SLEEP' &&
             <View className="addmoment_header">
                 <Text className="header_time" onClick={tapTime} style={{ color: getThemeColor(health.mode) }}>{dayjs().format('HH:mm')}</Text>
@@ -333,7 +283,14 @@ export default function AddMoment() {
                     (health.mode == 'EAT' || health.mode == 'ACTIVE') && <Text className="header_time" style={{ color: getThemeColor(health.mode) }} onClick={tapDuration}>{duration()}</Text>
                 }
             </View>
-        }
+        } */}
+
+        <View className="addmoment_header">
+            <Text onClick={() => {
+                setShowTimePicker(true)
+            }} style={{ marginLeft: 20, color: '#5C7099' }}>{time}</Text>
+            <Text style={{ marginLeft: 20, color: '#5C7099' }}>{title}</Text>
+        </View>
 
         <View className="form">
             <View>
@@ -360,8 +317,16 @@ export default function AddMoment() {
         {
             showPicker && timeContent()
         }
-
         {
+            showTimePicker && <PostMomentTime time={time} onChange={(e) => {
+                setTime(e)
+                setShowTimePicker(false)
+            }} dismiss={() => {
+                setShowTimePicker(false)
+            }} />
+        }
+
+        {/* {
             durationPicker && <DurationPicker
                 title='进食时长'
                 done={(time) => {
@@ -373,6 +338,9 @@ export default function AddMoment() {
                 dismiss={() => {
                     setDurationPicker(false)
                 }} time={durationT} />
+        } */}
+        {
+
         }
         {/* <Text> add eat detail</Text> */}
     </View>

+ 24 - 2
src/_health/pages/schedules_edit.tsx

@@ -8,11 +8,33 @@ import { getThemeColor } from "@/features/health/hooks/health_hooks";
 import Modal from "@/components/layout/Modal.weapp";
 import TimePicker from "@/features/common/TimePicker";
 import { AtSwipeAction } from "taro-ui"
-import Taro from "@tarojs/taro";
+import Taro, { useRouter } from "@tarojs/taro";
 import showAlert from "@/components/basic/Alert";
 import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
 
+let useRoute;
+let useNavigation;
+let scenario = '';
+if (process.env.TARO_ENV == 'rn') {
+    useRoute = require("@react-navigation/native").useRoute
+    useNavigation = require("@react-navigation/native").useNavigation
+}
+
 export default function SchedulesEdit() {
+    let navigation, showActionSheetWithOptions;
+
+    let router
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+    if (process.env.TARO_ENV == 'rn') {
+        router = useRoute()
+    }
+    else {
+        router = useRouter()
+    }
+    const selMode = router.params.mode;
     const [list, setList] = useState<any>([])
     const [labels, setLabels] = useState<any>([])
     const [showDel, setShowDel] = useState(false)
@@ -32,7 +54,7 @@ export default function SchedulesEdit() {
 
     function schedules() {
         let windows = ''
-        switch (health.mode) {
+        switch (selMode) {
             case 'FAST':
                 windows = 'FAST,EAT';
                 break

+ 3 - 3
src/_health/pages/schedules_list.tsx

@@ -138,7 +138,7 @@ export default function SchedulesList() {
     }
 
     function tapEdit() {
-        jumpPage('./schedules_edit')
+        jumpPage('./schedules_edit?mode='+selMode)
         return;
         let array: any = []
         switch (health.mode) {
@@ -228,12 +228,12 @@ export default function SchedulesList() {
     }
 
     return <View className='schedule_list_bg'>
-        {/* {
+        {
             selMode == '' && <View className='schedule_set_tabbar'>
                 <View onClick={()=>setSelTab(0)} className={selTab==0?'schedule_tab_sel':'schedule_tab_nor'}>按场景</View>
                 <View onClick={()=>setSelTab(1)} className={selTab==1?'schedule_tab_sel':'schedule_tab_nor'}>按时间</View>
             </View>
-        } */}
+        }
         <ScrollView enableFlex style={{ height: Taro.getSystemInfoSync().screenHeight - 220 - (selMode == '' ? rpxToPx(100) : 0) }} scrollY>
             <View style={{ display: 'flex', flexDirection: 'column' }}>
                 <View className='schedule_header_title'>{getTitle()}</View>

BIN
src/assets/_health/setting.png


File diff suppressed because it is too large
+ 2 - 2
src/components/basic/Icons.tsx


+ 4 - 2
src/features/health/MainConsole.tsx

@@ -125,7 +125,7 @@ export default function MainConsole(props: { type: WindowType }) {
                 return;
 
         }
-        jumpPage('/_health/pages/add_moment?moment=' + JSON.stringify(item))
+        jumpPage(`/_health/pages/add_moment?moment=${JSON.stringify(item)}&title=${item.title}&schedule_id=${item.schedule_id}&event_id=${item.event_id}`)
     }
 
     function operateTitle(item) {
@@ -408,7 +408,7 @@ export default function MainConsole(props: { type: WindowType }) {
         switch (health.mode) {
             case 'DAY':
             case 'NIGHT':
-                list = ['设置提醒','设置位置']
+                list = ['设置提醒', '设置位置']
                 break;
             case 'FAST':
             case 'SLEEP':
@@ -487,9 +487,11 @@ export default function MainConsole(props: { type: WindowType }) {
                             break;
                         case 'EAT':
                             //add snack
+                            jumpPage(`/_health/pages/add_moment?title=加餐&is_temp=${true}`)
                             break;
                         case 'ACTIVE':
                             //记录一次活动
+                            jumpPage(`/_health/pages/add_moment?title=&is_temp=${true}`)
                             break;
                     }
                 }

Some files were not shown because too many files changed in this diff