Skip to content

Instantly share code, notes, and snippets.

@sp0033212000
Created January 18, 2021 03:18
Show Gist options
  • Save sp0033212000/0ba82a3a6b88332de10a2d7c4bb49521 to your computer and use it in GitHub Desktop.
Save sp0033212000/0ba82a3a6b88332de10a2d7c4bb49521 to your computer and use it in GitHub Desktop.
import React, {
ComponentProps,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import {
StyleSheet,
View,
ScrollView,
TouchableOpacity,
LayoutChangeEvent,
GestureResponderEvent,
FlatList,
} from "react-native";
import {
backgroundStyle,
marginStyle,
utilsStyle,
} from "../../../../../../../styles/utils";
import moment, { Moment } from "moment";
import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome";
import Calendar from "../../../../../../General/Calendar/Calendar";
import Fonts from "../../../../../../General/Fonts";
import Space from "../../../../../../General/Space/Space";
import { useFocusEffect } from "@react-navigation/native";
import { isSameDay } from "../../../../../../../utils/dateHelper";
const OrderBrowseCalendar = () => {
const [showCalendar, setShowCalendar] = useState<boolean>(false);
const [dateValue, setDateValue] = useState<Moment | null>(null);
const [currentNode, setCurrentNode] = useState<TouchableOpacity | null>(null);
const [index, setIndex] = useState<number | null>(null);
const scrollRef = useRef<FlatList | null>(null);
const today = useRef(moment(new Date())).current;
useFocusEffect(
useCallback(() => {
if (global.browseDay) {
setDateValue(global.browseDay);
} else {
setToday();
}
}, [])
);
useFocusEffect(
useCallback(() => {
if (index === null) return;
scrollRef.current?.scrollToIndex({ animated: true, index });
// eslint-disable-next-line
}, [index, currentNode])
);
useEffect(() => {
console.log("node change");
}, [currentNode]);
const onLayout = (trigger: boolean, idx: number) => (
e: LayoutChangeEvent
) => {
if (!trigger) return;
setIndex(idx);
};
const setToday = () => {
setDateValue(today);
global.browseDay = today;
};
const onDayPress = (date: Moment, idx: number) => (
e: GestureResponderEvent
) => {
setDateValue(date);
global.browseDay = date;
setIndex(idx);
};
const dataAry = useMemo(() => {
if (!dateValue) return;
return [...new Array(dateValue.daysInMonth())].map((_, idx, ary) => ({
idx,
totalCount: ary.length,
}));
}, [dateValue]);
const uiDay = (idx: number, dayCount: number) => {
if (!dateValue) return;
const isLast = idx === dayCount - 1;
const itemDay = dateValue.clone().set({ date: idx + 1 });
const isToday = isSameDay(today, itemDay);
const isSelectedDay = isSameDay(dateValue, itemDay);
const dayIdx = itemDay.day() - 1;
const name = DAY_NAME[dayIdx < 0 ? 6 : dayIdx];
const isHoliday = dayIdx === -1 || dayIdx === 5;
let nameColor: ComponentProps<typeof Fonts>["fontColor"] = "GREY_3";
let fontColor: ComponentProps<typeof Fonts>["fontColor"] = "GREY_1";
let backgroundColor: string | undefined = undefined;
if (isToday) {
backgroundColor = `rgba(255, 76, 126, 0.15)`;
}
if (isHoliday) {
nameColor = "PRIMARY";
fontColor = "PRIMARY";
}
if (isSelectedDay) {
fontColor = "WHITE";
backgroundColor = `rgba(255, 76, 126, 1)`;
}
if (isSelectedDay) {
console.log("same", idx);
}
return (
<>
<TouchableOpacity
key={isSelectedDay ? "selected" : idx}
style={[style.item, utilsStyle.verticalCenter]}
onPress={onDayPress(itemDay, idx)}
onLayout={onLayout(isSelectedDay, idx)}
ref={isSelectedDay ? setCurrentNode : undefined}
>
<Fonts
fontColor={nameColor}
style={[style.day, marginStyle.bottom.sp4]}
fontSize="TINY"
>
{name}
</Fonts>
<View
style={[style.date, utilsStyle.flexCenter, { backgroundColor }]}
>
<Fonts fontColor={fontColor} fontSize="TINY">
{itemDay.date()}
</Fonts>
</View>
</TouchableOpacity>
{!isLast && <Space space={20} />}
</>
);
};
return (
<>
<Calendar
dateValue={dateValue}
onDateChange={setDateValue}
show={showCalendar}
close={() => setShowCalendar(false)}
/>
<View style={[style.container, backgroundStyle.grey5]}>
<View style={[utilsStyle.horizonCenter, marginStyle.bottom.sp20]}>
<Fonts fontWeight="700">2020年12月</Fonts>
<Space space={7} />
<TouchableOpacity onPress={() => setShowCalendar(true)}>
<FontAwesomeIcon size={18} icon={["far", "calendar-alt"]} />
</TouchableOpacity>
</View>
<FlatList
ref={scrollRef}
horizontal={true}
data={dataAry}
renderItem={({ item: { idx, totalCount } }) => (
<React.Fragment>{uiDay(idx, totalCount)}</React.Fragment>
)}
keyExtractor={(item) => JSON.stringify(item.idx)}
/>
</View>
</>
);
};
export default OrderBrowseCalendar;
const style = StyleSheet.create({
container: {
paddingTop: 16,
paddingBottom: 19,
paddingHorizontal: 24,
justifyContent: "space-between",
},
item: {
height: 51,
},
date: {
width: 30,
height: 30,
borderRadius: 15,
},
day: {
lineHeight: 17,
},
});
const DAY_NAME = ["一", "二", "三", "四", "五", "六", "日"];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment