fix themes modal, Add English to the trip information tab
This commit is contained in:
@@ -5,17 +5,19 @@ import CrewListTable from "@/components/tripInfo/CrewListTable";
|
||||
import FishingToolsTable from "@/components/tripInfo/FishingToolsList";
|
||||
import NetListTable from "@/components/tripInfo/NetListTable";
|
||||
import TripCostTable from "@/components/tripInfo/TripCostTable";
|
||||
import { useI18n } from "@/hooks/use-i18n";
|
||||
import { useThemeContext } from "@/hooks/use-theme-context";
|
||||
import { Platform, ScrollView, StyleSheet, Text, View } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export default function TripInfoScreen() {
|
||||
const { t } = useI18n();
|
||||
const { colors } = useThemeContext();
|
||||
return (
|
||||
<SafeAreaView style={styles.safeArea} edges={["top", "left", "right"]}>
|
||||
<View style={styles.header}>
|
||||
<Text style={[styles.titleText, { color: colors.text }]}>
|
||||
Thông Tin Chuyến Đi
|
||||
{t("trip.infoTrip")}
|
||||
</Text>
|
||||
<View style={styles.buttonWrapper}>
|
||||
<ButtonCreateNewHaulOrTrip />
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useI18n } from "@/hooks/use-i18n";
|
||||
import {
|
||||
ColorScheme as ThemeColorScheme,
|
||||
useTheme,
|
||||
useThemeContext,
|
||||
} from "@/hooks/use-theme-context";
|
||||
import { showErrorToast, showWarningToast } from "@/services/toast_service";
|
||||
import {
|
||||
@@ -44,6 +45,7 @@ export default function LoginScreen() {
|
||||
const [isShowingQRScanner, setIsShowingQRScanner] = useState(false);
|
||||
const { t, setLocale, locale } = useI18n();
|
||||
const { colors, colorScheme } = useTheme();
|
||||
const { setThemeMode } = useThemeContext();
|
||||
const styles = useMemo(
|
||||
() => createStyles(colors, colorScheme),
|
||||
[colors, colorScheme]
|
||||
@@ -312,6 +314,10 @@ export default function LoginScreen() {
|
||||
inactiveBackgroundColor={colors.surface}
|
||||
inactiveOverlayColor={colors.textSecondary}
|
||||
activeOverlayColor={colors.background}
|
||||
value={colorScheme === "light"}
|
||||
onChange={(val) => {
|
||||
setThemeMode(val ? "light" : "dark");
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useThemeContext } from "@/hooks/use-theme-context";
|
||||
import { AntDesign } from "@expo/vector-icons";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
@@ -93,6 +94,12 @@ const Select: React.FC<SelectProps> = ({
|
||||
|
||||
const sz = sizeMap[size];
|
||||
|
||||
// Theme colors from context (consistent with other components)
|
||||
const { colors } = useThemeContext();
|
||||
const selectBackgroundColor = disabled
|
||||
? colors.backgroundSecondary
|
||||
: colors.surface;
|
||||
|
||||
return (
|
||||
<View style={styles.wrapper}>
|
||||
<TouchableOpacity
|
||||
@@ -101,7 +108,8 @@ const Select: React.FC<SelectProps> = ({
|
||||
{
|
||||
height: sz.height,
|
||||
paddingHorizontal: sz.paddingHorizontal,
|
||||
opacity: disabled ? 0.6 : 1,
|
||||
backgroundColor: selectBackgroundColor,
|
||||
borderColor: disabled ? colors.border : colors.primary,
|
||||
},
|
||||
style,
|
||||
]}
|
||||
@@ -112,14 +120,18 @@ const Select: React.FC<SelectProps> = ({
|
||||
>
|
||||
<View style={styles.content}>
|
||||
{loading ? (
|
||||
<ActivityIndicator size="small" color="#4ecdc4" />
|
||||
<ActivityIndicator size="small" color={colors.primary} />
|
||||
) : (
|
||||
<Text
|
||||
style={[
|
||||
styles.text,
|
||||
{
|
||||
fontSize: sz.fontSize,
|
||||
color: selectedValue ? "#111" : "#999",
|
||||
color: disabled
|
||||
? colors.textSecondary
|
||||
: selectedValue
|
||||
? colors.text
|
||||
: colors.textSecondary,
|
||||
},
|
||||
]}
|
||||
numberOfLines={1}
|
||||
@@ -131,24 +143,41 @@ const Select: React.FC<SelectProps> = ({
|
||||
<View style={styles.suffix}>
|
||||
{allowClear && selectedValue && !loading ? (
|
||||
<TouchableOpacity onPress={handleClear} style={styles.icon}>
|
||||
<AntDesign name="close" size={16} color="#999" />
|
||||
<AntDesign name="close" size={16} color={colors.textSecondary} />
|
||||
</TouchableOpacity>
|
||||
) : null}
|
||||
<AntDesign
|
||||
name={isOpen ? "up" : "down"}
|
||||
size={14}
|
||||
color="#999"
|
||||
color={colors.textSecondary}
|
||||
style={styles.arrow}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
{isOpen && (
|
||||
<View style={[styles.dropdown, { top: containerHeight }]}>
|
||||
<View
|
||||
style={[
|
||||
styles.dropdown,
|
||||
{
|
||||
top: containerHeight,
|
||||
backgroundColor: colors.background,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{showSearch && (
|
||||
<TextInput
|
||||
style={styles.searchInput}
|
||||
style={[
|
||||
styles.searchInput,
|
||||
{
|
||||
backgroundColor: colors.background,
|
||||
borderColor: colors.border,
|
||||
color: colors.text,
|
||||
},
|
||||
]}
|
||||
placeholder="Search..."
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
value={searchText}
|
||||
onChangeText={setSearchText}
|
||||
autoFocus
|
||||
@@ -160,8 +189,13 @@ const Select: React.FC<SelectProps> = ({
|
||||
key={item.value}
|
||||
style={[
|
||||
styles.option,
|
||||
{
|
||||
borderBottomColor: colors.separator,
|
||||
},
|
||||
item.disabled && styles.optionDisabled,
|
||||
selectedValue === item.value && styles.optionSelected,
|
||||
selectedValue === item.value && {
|
||||
backgroundColor: colors.primary + "20", // Add transparency to primary color
|
||||
},
|
||||
]}
|
||||
onPress={() => !item.disabled && handleSelect(item.value)}
|
||||
disabled={item.disabled}
|
||||
@@ -169,14 +203,22 @@ const Select: React.FC<SelectProps> = ({
|
||||
<Text
|
||||
style={[
|
||||
styles.optionText,
|
||||
item.disabled && styles.optionTextDisabled,
|
||||
selectedValue === item.value && styles.optionTextSelected,
|
||||
{
|
||||
color: colors.text,
|
||||
},
|
||||
item.disabled && {
|
||||
color: colors.textSecondary,
|
||||
},
|
||||
selectedValue === item.value && {
|
||||
color: colors.primary,
|
||||
fontWeight: "600",
|
||||
},
|
||||
]}
|
||||
>
|
||||
{item.label}
|
||||
</Text>
|
||||
{selectedValue === item.value && (
|
||||
<AntDesign name="check" size={16} color="#4ecdc4" />
|
||||
<AntDesign name="check" size={16} color={colors.primary} />
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
@@ -193,9 +235,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
container: {
|
||||
borderWidth: 1,
|
||||
borderColor: "#e6e6e6",
|
||||
borderRadius: 8,
|
||||
backgroundColor: "#fff",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
@@ -204,7 +244,7 @@ const styles = StyleSheet.create({
|
||||
flex: 1,
|
||||
},
|
||||
text: {
|
||||
color: "#111",
|
||||
// Color is set dynamically via theme
|
||||
},
|
||||
suffix: {
|
||||
flexDirection: "row",
|
||||
@@ -220,9 +260,7 @@ const styles = StyleSheet.create({
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: "#fff",
|
||||
borderWidth: 1,
|
||||
borderColor: "#e6e6e6",
|
||||
borderTopWidth: 0,
|
||||
borderRadius: 10,
|
||||
borderBottomLeftRadius: 8,
|
||||
@@ -236,7 +274,6 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
searchInput: {
|
||||
borderWidth: 1,
|
||||
borderColor: "#e6e6e6",
|
||||
borderRadius: 4,
|
||||
padding: 8,
|
||||
margin: 8,
|
||||
@@ -247,7 +284,6 @@ const styles = StyleSheet.create({
|
||||
option: {
|
||||
padding: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#f0f0f0",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
@@ -255,20 +291,11 @@ const styles = StyleSheet.create({
|
||||
optionDisabled: {
|
||||
opacity: 0.5,
|
||||
},
|
||||
optionSelected: {
|
||||
backgroundColor: "#f6ffed",
|
||||
},
|
||||
// optionSelected is handled dynamically via inline styles
|
||||
optionText: {
|
||||
fontSize: 16,
|
||||
color: "#111",
|
||||
},
|
||||
optionTextDisabled: {
|
||||
color: "#999",
|
||||
},
|
||||
optionTextSelected: {
|
||||
color: "#4ecdc4",
|
||||
fontWeight: "600",
|
||||
},
|
||||
// optionTextDisabled and optionTextSelected are handled dynamically via inline styles
|
||||
});
|
||||
|
||||
export default Select;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Text, View } from "react-native";
|
||||
import { ThemedText } from "@/components/themed-text";
|
||||
import { useAppTheme } from "@/hooks/use-app-theme";
|
||||
import { View } from "react-native";
|
||||
|
||||
interface DescriptionProps {
|
||||
title?: string;
|
||||
@@ -8,10 +10,15 @@ export const Description = ({
|
||||
title = "",
|
||||
description = "",
|
||||
}: DescriptionProps) => {
|
||||
const { colors } = useAppTheme();
|
||||
return (
|
||||
<View className="flex-row gap-2 ">
|
||||
<Text className="opacity-50 text-lg">{title}:</Text>
|
||||
<Text className="text-lg">{description}</Text>
|
||||
<ThemedText
|
||||
style={{ color: colors.textSecondary, fontSize: 16 }}
|
||||
>
|
||||
{title}:
|
||||
</ThemedText>
|
||||
<ThemedText style={{ fontSize: 16 }}>{description}</ThemedText>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useAppTheme } from "@/hooks/use-app-theme";
|
||||
import { useI18n } from "@/hooks/use-i18n";
|
||||
import { convertToDMS, kmhToKnot } from "@/utils/geom";
|
||||
import { MaterialIcons } from "@expo/vector-icons";
|
||||
@@ -15,6 +16,8 @@ const GPSInfoPanel = ({ gpsData }: GPSInfoPanelProps) => {
|
||||
const translateY = useRef(new Animated.Value(0)).current;
|
||||
const blockBottom = useRef(new Animated.Value(0)).current;
|
||||
const { t } = useI18n();
|
||||
const { colors, styles } = useAppTheme();
|
||||
|
||||
useEffect(() => {
|
||||
Animated.timing(translateY, {
|
||||
toValue: isExpanded ? 0 : 200, // Dịch chuyển xuống 200px khi thu gọn
|
||||
@@ -44,45 +47,35 @@ const GPSInfoPanel = ({ gpsData }: GPSInfoPanelProps) => {
|
||||
position: "absolute",
|
||||
bottom: blockBottom,
|
||||
left: 5,
|
||||
// width: 48,
|
||||
// height: 48,
|
||||
// backgroundColor: "blue",
|
||||
borderRadius: 4,
|
||||
zIndex: 30,
|
||||
}}
|
||||
>
|
||||
<ButtonCreateNewHaulOrTrip gpsData={gpsData} />
|
||||
{/* <TouchableOpacity
|
||||
onPress={() => {
|
||||
// showInfoToast("oad");
|
||||
showWarningToast("This is a warning toast!");
|
||||
}}
|
||||
className="absolute top-2 right-2 z-10 bg-white rounded-full p-1"
|
||||
>
|
||||
<MaterialIcons
|
||||
name={isExpanded ? "close" : "close"}
|
||||
size={20}
|
||||
color="#666"
|
||||
/>
|
||||
</TouchableOpacity> */}
|
||||
</Animated.View>
|
||||
|
||||
<Animated.View
|
||||
style={{
|
||||
transform: [{ translateY }],
|
||||
}}
|
||||
className="absolute bottom-0 gap-3 right-0 p-3 left-0 h-auto w-full rounded-t-xl bg-white shadow-md"
|
||||
style={[
|
||||
styles.card,
|
||||
{
|
||||
transform: [{ translateY }],
|
||||
backgroundColor: colors.card,
|
||||
borderRadius: 0,
|
||||
},
|
||||
]}
|
||||
className="absolute bottom-0 gap-5 right-0 px-4 pt-12 pb-2 left-0 h-auto w-full rounded-t-xl shadow-md"
|
||||
onLayout={(event) => setPanelHeight(event.nativeEvent.layout.height)}
|
||||
>
|
||||
{/* Nút toggle ở top-right */}
|
||||
<TouchableOpacity
|
||||
onPress={togglePanel}
|
||||
className="absolute top-2 right-2 z-10 bg-white rounded-full p-1"
|
||||
className="absolute top-2 right-2 z-10 rounded-full p-1"
|
||||
style={{ backgroundColor: colors.card }}
|
||||
>
|
||||
<MaterialIcons
|
||||
name={isExpanded ? "close" : "close"}
|
||||
size={20}
|
||||
color="#666"
|
||||
color={colors.icon}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -120,9 +113,10 @@ const GPSInfoPanel = ({ gpsData }: GPSInfoPanelProps) => {
|
||||
{!isExpanded && (
|
||||
<TouchableOpacity
|
||||
onPress={togglePanel}
|
||||
className="absolute bottom-5 right-2 z-20 bg-white rounded-full p-2 shadow-lg"
|
||||
className="absolute bottom-5 right-2 z-20 rounded-full p-2 shadow-lg"
|
||||
style={{ backgroundColor: colors.card }}
|
||||
>
|
||||
<MaterialIcons name="info-outline" size={24} />
|
||||
<MaterialIcons name="info-outline" size={24} color={colors.icon} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { StyleSheet, Text, TextInput, View } from "react-native";
|
||||
import IconButton from "../IconButton";
|
||||
import Select from "../Select";
|
||||
import Modal from "../ui/modal";
|
||||
import { useThemeColor } from "@/hooks/use-theme-color";
|
||||
|
||||
const SosButton = () => {
|
||||
const [sosData, setSosData] = useState<Model.SosResponse | null>();
|
||||
@@ -22,6 +23,16 @@ const SosButton = () => {
|
||||
const [customMessage, setCustomMessage] = useState("");
|
||||
const [errors, setErrors] = useState<{ [key: string]: string }>({});
|
||||
const { t } = useI18n();
|
||||
|
||||
// Theme colors
|
||||
const textColor = useThemeColor({}, 'text');
|
||||
const borderColor = useThemeColor({}, 'border');
|
||||
const errorColor = useThemeColor({}, 'error');
|
||||
const backgroundColor = useThemeColor({}, 'background');
|
||||
|
||||
// Dynamic styles
|
||||
const styles = SosButtonStyles(textColor, borderColor, errorColor, backgroundColor);
|
||||
|
||||
const sosOptions = [
|
||||
...sosMessage.map((msg) => ({
|
||||
ma: msg.ma,
|
||||
@@ -176,7 +187,7 @@ const SosButton = () => {
|
||||
errors.customMessage ? styles.errorInput : {},
|
||||
]}
|
||||
placeholder={t("home.sos.enterStatus")}
|
||||
placeholderTextColor="#999"
|
||||
placeholderTextColor={textColor + '99'} // Add transparency
|
||||
value={customMessage}
|
||||
onChangeText={(text) => {
|
||||
setCustomMessage(text);
|
||||
@@ -201,7 +212,7 @@ const SosButton = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const SosButtonStyles = (textColor: string, borderColor: string, errorColor: string, backgroundColor: string) => StyleSheet.create({
|
||||
formGroup: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
@@ -209,26 +220,27 @@ const styles = StyleSheet.create({
|
||||
fontSize: 14,
|
||||
fontWeight: "600",
|
||||
marginBottom: 8,
|
||||
color: "#333",
|
||||
color: textColor,
|
||||
},
|
||||
errorBorder: {
|
||||
borderColor: "#ff4444",
|
||||
borderColor: errorColor,
|
||||
},
|
||||
input: {
|
||||
borderWidth: 1,
|
||||
borderColor: "#ddd",
|
||||
borderColor: borderColor,
|
||||
borderRadius: 8,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
fontSize: 14,
|
||||
color: "#333",
|
||||
color: textColor,
|
||||
backgroundColor: backgroundColor,
|
||||
textAlignVertical: "top",
|
||||
},
|
||||
errorInput: {
|
||||
borderColor: "#ff4444",
|
||||
borderColor: errorColor,
|
||||
},
|
||||
errorText: {
|
||||
color: "#ff4444",
|
||||
color: errorColor,
|
||||
fontSize: 12,
|
||||
marginTop: 4,
|
||||
},
|
||||
|
||||
@@ -15,7 +15,7 @@ export const InfoSection: React.FC<InfoSectionProps> = ({
|
||||
const { t } = useI18n();
|
||||
const { colors } = useThemeContext();
|
||||
const styles = React.useMemo(() => createStyles(colors), [colors]);
|
||||
|
||||
|
||||
if (!fishingLog) {
|
||||
return null;
|
||||
}
|
||||
@@ -80,7 +80,7 @@ const createStyles = (colors: any) =>
|
||||
borderRadius: 8,
|
||||
padding: 12,
|
||||
marginBottom: 12,
|
||||
backgroundColor: colors.backgroundSecondary,
|
||||
backgroundColor: colors.surfaceSecondary,
|
||||
},
|
||||
infoRow: {
|
||||
flexDirection: "row",
|
||||
|
||||
@@ -58,7 +58,7 @@ export const createStyles = (colors: typeof Colors.light) =>
|
||||
marginBottom: 15,
|
||||
},
|
||||
fishCard: {
|
||||
backgroundColor: colors.card,
|
||||
backgroundColor: colors.surfaceSecondary,
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
marginBottom: 16,
|
||||
@@ -95,7 +95,7 @@ export const createStyles = (colors: typeof Colors.light) =>
|
||||
},
|
||||
input: {
|
||||
borderWidth: 1,
|
||||
borderColor: colors.border,
|
||||
borderColor: colors.primary,
|
||||
borderRadius: 8,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 10,
|
||||
@@ -106,7 +106,7 @@ export const createStyles = (colors: typeof Colors.light) =>
|
||||
inputDisabled: {
|
||||
backgroundColor: colors.backgroundSecondary,
|
||||
color: colors.textSecondary,
|
||||
borderColor: colors.separator,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
errorText: {
|
||||
color: colors.error,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import type { ComponentProps } from "react";
|
||||
import { useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
Animated,
|
||||
OpaqueColorValue,
|
||||
@@ -29,7 +29,7 @@ const PRESS_FEEDBACK_DURATION = 120;
|
||||
|
||||
type IoniconName = ComponentProps<typeof Ionicons>["name"];
|
||||
|
||||
type RotateSwitchProps = {
|
||||
type SliceSwitchProps = {
|
||||
size?: SwitchSize;
|
||||
leftIcon?: IoniconName;
|
||||
leftIconColor?: string | OpaqueColorValue | undefined;
|
||||
@@ -42,6 +42,7 @@ type RotateSwitchProps = {
|
||||
activeOverlayColor?: string;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
onChange?: (value: boolean) => void;
|
||||
value?: boolean;
|
||||
};
|
||||
|
||||
const SliceSwitch = ({
|
||||
@@ -57,19 +58,28 @@ const SliceSwitch = ({
|
||||
activeOverlayColor = "#000",
|
||||
style,
|
||||
onChange,
|
||||
}: RotateSwitchProps) => {
|
||||
value,
|
||||
}: SliceSwitchProps) => {
|
||||
const { width: containerWidth, height: containerHeight } =
|
||||
SIZE_PRESETS[size] ?? SIZE_PRESETS.md;
|
||||
const animationDuration = Math.max(duration ?? DEFAULT_TOGGLE_DURATION, 0);
|
||||
const [isOn, setIsOn] = useState(false);
|
||||
const [bgOn, setBgOn] = useState(false);
|
||||
const progress = useRef(new Animated.Value(0)).current;
|
||||
const [isOn, setIsOn] = useState(value ?? false);
|
||||
const [bgOn, setBgOn] = useState(value ?? false);
|
||||
const progress = useRef(new Animated.Value(value ? 1 : 0)).current;
|
||||
const pressScale = useRef(new Animated.Value(1)).current;
|
||||
const overlayTranslateX = useRef(new Animated.Value(0)).current;
|
||||
const overlayTranslateX = useRef(
|
||||
new Animated.Value(value ? containerWidth / 2 : 0)
|
||||
).current;
|
||||
const listenerIdRef = useRef<string | number | null>(null);
|
||||
|
||||
const handleToggle = () => {
|
||||
const next = !isOn;
|
||||
// Sync with external value prop if provided
|
||||
useEffect(() => {
|
||||
if (value !== undefined && value !== isOn) {
|
||||
animateToValue(value);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
const animateToValue = (next: boolean) => {
|
||||
const targetValue = next ? 1 : 0;
|
||||
const overlayTarget = next ? containerWidth / 2 : 0;
|
||||
|
||||
@@ -81,7 +91,6 @@ const SliceSwitch = ({
|
||||
overlayTranslateX.setValue(overlayTarget);
|
||||
setIsOn(next);
|
||||
setBgOn(next);
|
||||
onChange?.(next);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,7 +109,6 @@ const SliceSwitch = ({
|
||||
}),
|
||||
]).start(() => {
|
||||
setBgOn(next);
|
||||
onChange?.(next);
|
||||
});
|
||||
|
||||
// Remove any previous listener
|
||||
@@ -132,6 +140,14 @@ const SliceSwitch = ({
|
||||
});
|
||||
};
|
||||
|
||||
const handleToggle = () => {
|
||||
const next = !isOn;
|
||||
if (value === undefined) {
|
||||
animateToValue(next);
|
||||
}
|
||||
onChange?.(next);
|
||||
};
|
||||
|
||||
const handlePressIn = () => {
|
||||
pressScale.stopAnimation();
|
||||
Animated.timing(pressScale, {
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Provides styled components and theme utilities
|
||||
*/
|
||||
|
||||
import { useThemeContext } from "@/hooks/use-theme-context";
|
||||
import { useMemo } from "react";
|
||||
import { StyleSheet, TextStyle, ViewStyle } from "react-native";
|
||||
import { useThemeContext } from "@/hooks/use-theme-context";
|
||||
|
||||
export function useAppTheme() {
|
||||
const { colors, colorScheme, themeMode, setThemeMode, getColor } =
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
}
|
||||
},
|
||||
"trip": {
|
||||
"infoTrip": "Trip Information",
|
||||
"createNewTrip": "Create New Trip",
|
||||
"endTrip": "End Trip",
|
||||
"cancelTrip": "Cancel Trip",
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
}
|
||||
},
|
||||
"trip": {
|
||||
"infoTrip": "Thông Tin Chuyến Đi",
|
||||
"createNewTrip": "Tạo chuyến mới",
|
||||
"endTrip": "Kết thúc chuyến",
|
||||
"cancelTrip": "Hủy chuyến",
|
||||
|
||||
Reference in New Issue
Block a user