Compare commits
8 Commits
9d1c4c9744
...
c2fedc99fd
| Author | SHA1 | Date | |
|---|---|---|---|
| c2fedc99fd | |||
| 0ce41b22da | |||
| 0db4c0c74e | |||
| a8c5117cb7 | |||
| a764210a61 | |||
| cff3516aa2 | |||
| 08571c543d | |||
| d2ec5d7bce |
7
app.json
7
app.json
@ -4,7 +4,7 @@
|
|||||||
"slug": "memowake",
|
"slug": "memowake",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"orientation": "portrait",
|
"orientation": "portrait",
|
||||||
"icon": "",
|
"icon": "./assets/icons/png/app.png",
|
||||||
"scheme": "memowake",
|
"scheme": "memowake",
|
||||||
"userInterfaceStyle": "automatic",
|
"userInterfaceStyle": "automatic",
|
||||||
"newArchEnabled": true,
|
"newArchEnabled": true,
|
||||||
@ -48,7 +48,7 @@
|
|||||||
"web": {
|
"web": {
|
||||||
"bundler": "metro",
|
"bundler": "metro",
|
||||||
"output": "static",
|
"output": "static",
|
||||||
"favicon": ""
|
"favicon": "./assets/icons/png/app.png"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"expo-router",
|
"expo-router",
|
||||||
@ -96,8 +96,7 @@
|
|||||||
"router": {},
|
"router": {},
|
||||||
"eas": {
|
"eas": {
|
||||||
"projectId": "04721dd4-6b15-495a-b9ec-98187c613172"
|
"projectId": "04721dd4-6b15-495a-b9ec-98187c613172"
|
||||||
},
|
}
|
||||||
"API_ENDPOINT": "http://192.168.31.115:18080/api"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import * as Notifications from 'expo-notifications';
|
|||||||
import { Tabs } from 'expo-router';
|
import { Tabs } from 'expo-router';
|
||||||
import * as SecureStore from 'expo-secure-store';
|
import * as SecureStore from 'expo-secure-store';
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Platform } from 'react-native';
|
import { Platform } from 'react-native';
|
||||||
|
|
||||||
interface PollingData {
|
interface PollingData {
|
||||||
@ -17,6 +18,7 @@ interface PollingData {
|
|||||||
extra: any;
|
extra: any;
|
||||||
}
|
}
|
||||||
export default function TabLayout() {
|
export default function TabLayout() {
|
||||||
|
const { t } = useTranslation();
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
const [pollingData, setPollingData] = useState<PollingData[]>([]);
|
const [pollingData, setPollingData] = useState<PollingData[]>([]);
|
||||||
const pollingInterval = useRef<NodeJS.Timeout | number>(null);
|
const pollingInterval = useRef<NodeJS.Timeout | number>(null);
|
||||||
@ -280,6 +282,27 @@ export default function TabLayout() {
|
|||||||
tabBarStyle: { display: 'none' } // 确保在标签栏中不显示
|
tabBarStyle: { display: 'none' } // 确保在标签栏中不显示
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{/* 隐私协议 */}
|
||||||
|
<Tabs.Screen
|
||||||
|
name="privacy-policy"
|
||||||
|
options={{
|
||||||
|
title: 'privacy-policy',
|
||||||
|
tabBarButton: () => null, // 隐藏底部标签栏
|
||||||
|
headerShown: false, // 隐藏导航栏
|
||||||
|
tabBarStyle: { display: 'none' } // 确保在标签栏中不显示
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Support Screen */}
|
||||||
|
<Tabs.Screen
|
||||||
|
name="support"
|
||||||
|
options={{
|
||||||
|
title: t('tabTitle', { ns: 'support' }),
|
||||||
|
tabBarButton: () => null, // 隐藏底部标签栏
|
||||||
|
headerShown: false, // 隐藏导航栏
|
||||||
|
tabBarStyle: { display: 'none' } // 确保在标签栏中不显示
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Debug Screen - only in development */}
|
{/* Debug Screen - only in development */}
|
||||||
{process.env.NODE_ENV === 'development' && (
|
{process.env.NODE_ENV === 'development' && (
|
||||||
|
|||||||
@ -18,6 +18,8 @@ export default function HomeScreen() {
|
|||||||
router.replace('/ask')
|
router.replace('/ask')
|
||||||
}, false).then(() => {
|
}, false).then(() => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
}).catch(() => {
|
||||||
|
setIsLoading(false);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import ConversationsSvg from '@/assets/icons/svg/conversations.svg';
|
import ConversationsSvg from '@/assets/icons/svg/conversations.svg';
|
||||||
import MoreArrowSvg from '@/assets/icons/svg/moreArrow.svg';
|
|
||||||
import PointsSvg from '@/assets/icons/svg/points.svg';
|
import PointsSvg from '@/assets/icons/svg/points.svg';
|
||||||
import StoriesSvg from '@/assets/icons/svg/stories.svg';
|
import StoriesSvg from '@/assets/icons/svg/stories.svg';
|
||||||
import UsedStorageSvg from '@/assets/icons/svg/usedStorage.svg';
|
import UsedStorageSvg from '@/assets/icons/svg/usedStorage.svg';
|
||||||
@ -87,13 +86,10 @@ export default function OwnerPage() {
|
|||||||
|
|
||||||
{/* 资源数据 */}
|
{/* 资源数据 */}
|
||||||
<View style={styles.resourceContainer}>
|
<View style={styles.resourceContainer}>
|
||||||
<View style={{ gap: 16, width: "80%" }}>
|
<View style={{ gap: 16 }}>
|
||||||
<ResourceComponent title={t("generalSetting.usedStorage", { ns: "personal" })} data={{ all: userInfoDetails.total_bytes, used: countData.used_bytes }} icon={<UsedStorageSvg />} isFormatBytes={true} />
|
<ResourceComponent title={t("generalSetting.usedStorage", { ns: "personal" })} data={{ all: userInfoDetails.total_bytes, used: countData.used_bytes }} icon={<UsedStorageSvg />} isFormatBytes={true} />
|
||||||
<ResourceComponent title={t("generalSetting.remainingPoints", { ns: "personal" })} data={{ all: userInfoDetails.total_points, used: userInfoDetails.remain_points }} icon={<PointsSvg />} />
|
<ResourceComponent title={t("generalSetting.remainingPoints", { ns: "personal" })} data={{ all: userInfoDetails.total_points, used: userInfoDetails.remain_points }} icon={<PointsSvg />} />
|
||||||
</View>
|
</View>
|
||||||
<View style={{ alignItems: 'flex-end', flex: 1 }}>
|
|
||||||
<MoreArrowSvg />
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
{/* 分类 */}
|
{/* 分类 */}
|
||||||
<CarouselComponent data={userInfoDetails?.material_counter} />
|
<CarouselComponent data={userInfoDetails?.material_counter} />
|
||||||
|
|||||||
159
app/(tabs)/privacy-policy.tsx
Normal file
159
app/(tabs)/privacy-policy.tsx
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
import { fetchApi } from "@/lib/server-api-util";
|
||||||
|
import { Policy } from "@/types/personal-info";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
||||||
|
import RenderHtml from 'react-native-render-html';
|
||||||
|
|
||||||
|
const PrivacyPolicy = () => {
|
||||||
|
const [article, setArticle] = useState<Policy>({} as Policy);
|
||||||
|
useEffect(() => {
|
||||||
|
const loadArticle = async () => {
|
||||||
|
fetchApi<Policy>(`/system-config/policy/privacy_policy`).then((res: any) => {
|
||||||
|
setArticle(res)
|
||||||
|
}).catch((error: any) => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loadArticle();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!article) {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text>加载中...</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.centeredView}>
|
||||||
|
<View style={styles.modalView}>
|
||||||
|
<View style={styles.modalHeader}>
|
||||||
|
<Text style={{ opacity: 0 }}>Settings</Text>
|
||||||
|
<Text style={styles.modalTitle}>{'Privacy Policy'}</Text>
|
||||||
|
<TouchableOpacity style={{ opacity: 0 }}>
|
||||||
|
<Text style={styles.closeButton}>×</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<ScrollView style={styles.modalContent} showsVerticalScrollIndicator={false}>
|
||||||
|
<RenderHtml
|
||||||
|
source={{ html: article.content }}
|
||||||
|
tagsStyles={{
|
||||||
|
p: { fontSize: 16, lineHeight: 24 },
|
||||||
|
strong: { fontWeight: 'bold' },
|
||||||
|
em: { fontStyle: 'italic' },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PrivacyPolicy;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
centeredView: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
modalView: {
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
},
|
||||||
|
modalHeader: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
modalTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#4C320C',
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
fontSize: 28,
|
||||||
|
color: '#4C320C',
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
|
modalContent: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
modalText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#4C320C',
|
||||||
|
},
|
||||||
|
premium: {
|
||||||
|
backgroundColor: "#FAF9F6",
|
||||||
|
padding: 16,
|
||||||
|
borderRadius: 24,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 4,
|
||||||
|
backgroundColor: '#FAF9F6',
|
||||||
|
borderRadius: 24,
|
||||||
|
paddingVertical: 8
|
||||||
|
},
|
||||||
|
item: {
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 8,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
itemText: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: '600',
|
||||||
|
color: '#4C320C',
|
||||||
|
},
|
||||||
|
upgradeButton: {
|
||||||
|
backgroundColor: '#E2793F',
|
||||||
|
borderRadius: 20,
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 8,
|
||||||
|
},
|
||||||
|
upgradeButtonText: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "600"
|
||||||
|
},
|
||||||
|
switchContainer: {
|
||||||
|
width: 50,
|
||||||
|
height: 30,
|
||||||
|
borderRadius: 15,
|
||||||
|
justifyContent: 'center',
|
||||||
|
paddingHorizontal: 2,
|
||||||
|
},
|
||||||
|
switchOn: {
|
||||||
|
backgroundColor: '#E2793F',
|
||||||
|
alignItems: 'flex-end',
|
||||||
|
},
|
||||||
|
switchOff: {
|
||||||
|
backgroundColor: '#E5E5E5',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
},
|
||||||
|
switchCircle: {
|
||||||
|
width: 26,
|
||||||
|
height: 26,
|
||||||
|
borderRadius: 13,
|
||||||
|
},
|
||||||
|
switchCircleOn: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
},
|
||||||
|
switchCircleOff: {
|
||||||
|
backgroundColor: '#A5A5A5',
|
||||||
|
},
|
||||||
|
});
|
||||||
67
app/(tabs)/support.tsx
Normal file
67
app/(tabs)/support.tsx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { Ionicons } from '@expo/vector-icons';
|
||||||
|
import { LinearGradient } from 'expo-linear-gradient';
|
||||||
|
import Head from 'expo-router/head';
|
||||||
|
import React from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Linking, Text, TouchableOpacity, View } from 'react-native';
|
||||||
|
|
||||||
|
const SupportScreen = () => {
|
||||||
|
const { t } = useTranslation('support');
|
||||||
|
const handleWeChatSupport = () => {
|
||||||
|
Linking.openURL('https://work.weixin.qq.com/kfid/kfca0ac87f4e05e8bfd');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEmailSupport = () => {
|
||||||
|
Linking.openURL('mailto:memowake@fairclip.cn');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>{t('pageTitle')}</title>
|
||||||
|
</Head>
|
||||||
|
<LinearGradient
|
||||||
|
colors={['#FFB645', '#E2793F']}
|
||||||
|
className="flex-1 items-center justify-center p-6"
|
||||||
|
>
|
||||||
|
<View className="items-center mb-12">
|
||||||
|
<Text className="text-white text-5xl font-extrabold tracking-tight">
|
||||||
|
MemoWake
|
||||||
|
</Text>
|
||||||
|
<Text className="text-white/90 text-2xl mt-4 text-center max-w-xs">
|
||||||
|
{t('title')}
|
||||||
|
</Text>
|
||||||
|
<Text className="text-white/90 text-lg mt-4 text-center max-w-xs">
|
||||||
|
{t('description')}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="w-full max-w-xs">
|
||||||
|
<TouchableOpacity
|
||||||
|
className="bg-white/90 rounded-xl px-6 py-4 flex-row items-center justify-center shadow-lg mb-5"
|
||||||
|
onPress={handleWeChatSupport}
|
||||||
|
activeOpacity={0.8}
|
||||||
|
>
|
||||||
|
<Ionicons name="chatbubbles-outline" size={24} color="black" />
|
||||||
|
<Text className="text-black font-bold text-lg ml-3">
|
||||||
|
{t('onlineSupport')}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
className="bg-black/80 rounded-xl px-6 py-4 flex-row items-center justify-center shadow-lg"
|
||||||
|
onPress={handleEmailSupport}
|
||||||
|
activeOpacity={0.8}
|
||||||
|
>
|
||||||
|
<Ionicons name="mail-outline" size={24} color="white" />
|
||||||
|
<Text className="text-white font-bold text-lg ml-3">
|
||||||
|
{t('emailSupport')}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</LinearGradient>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SupportScreen;
|
||||||
BIN
assets/icons/png/app.png
Normal file
BIN
assets/icons/png/app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
61
assets/icons/svg/app.svg
Normal file
61
assets/icons/svg/app.svg
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<svg width="578" height="577" viewBox="0 0 578 577" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_215_188)">
|
||||||
|
<g clip-path="url(#clip0_215_188)">
|
||||||
|
<rect x="3" width="572.333" height="572.333" rx="111.784" fill="white"/>
|
||||||
|
<rect x="3" width="572.333" height="572.333" fill="#AC7E35"/>
|
||||||
|
<path d="M34.4206 192.01C32.8885 178.266 65.8095 177.448 82.4616 178.758L56.5555 209.322C48.4291 212.492 35.9527 205.754 34.4206 192.01Z" fill="#FFDBA3"/>
|
||||||
|
<path d="M41.5631 191.094C39.1999 179.937 62.1246 182.378 73.8823 184.994L60.656 199.713C55.2763 201.489 43.9263 202.252 41.5631 191.094Z" fill="#AC7E35"/>
|
||||||
|
<path d="M198.913 27.5173C185.168 25.9852 184.351 58.9062 185.661 75.5583L216.225 49.6522C219.395 41.5258 212.657 29.0493 198.913 27.5173Z" fill="#FFDBA3"/>
|
||||||
|
<path d="M197.997 34.6598C186.84 32.2966 189.281 55.2212 191.897 66.979L206.616 53.7527C208.392 48.373 209.154 37.0229 197.997 34.6598Z" fill="#AC7E35"/>
|
||||||
|
<path d="M30.7421 448.573C-38.1574 191.436 197.139 -43.8603 454.275 25.0392L629.664 72.0346C886.801 140.934 972.926 462.355 784.689 650.592L656.295 778.986C468.058 967.223 146.637 881.099 77.7375 623.962L30.7421 448.573Z" fill="#FFD18A"/>
|
||||||
|
<rect x="217.479" y="240.655" width="13.6147" height="19.0606" rx="6.80735" transform="rotate(135 217.479 240.655)" fill="#4C320C"/>
|
||||||
|
<rect x="252.138" y="205.996" width="13.6147" height="19.0606" rx="6.80735" transform="rotate(135 252.138 205.996)" fill="#4C320C"/>
|
||||||
|
<path d="M192.499 462.813C162.296 299.481 305.191 156.586 468.523 186.789L654.544 221.189C842.135 255.878 913.874 486.75 778.979 621.646L627.356 773.269C492.46 908.164 261.588 836.425 226.899 648.835L192.499 462.813Z" fill="#FFF8DE"/>
|
||||||
|
<g filter="url(#filter1_i_215_188)">
|
||||||
|
<ellipse cx="447.564" cy="174.232" rx="223.281" ry="159.292" transform="rotate(-45 447.564 174.232)" fill="#FFF8DE"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter2_i_215_188)">
|
||||||
|
<ellipse cx="178.97" cy="442.827" rx="221.92" ry="159.292" transform="rotate(-45 178.97 442.827)" fill="#FFF8DE"/>
|
||||||
|
</g>
|
||||||
|
<ellipse cx="256.948" cy="253.172" rx="16.3376" ry="12.2532" transform="rotate(135 256.948 253.172)" fill="#FFB8B9"/>
|
||||||
|
<ellipse cx="38.9009" cy="15.5185" rx="38.9009" ry="15.5185" transform="matrix(0.934357 -0.356338 -0.356338 -0.934357 493.079 394.049)" fill="#FFD38D"/>
|
||||||
|
<ellipse cx="358.82" cy="530.763" rx="38.9009" ry="15.5185" transform="rotate(110.875 358.82 530.763)" fill="#FFD38D"/>
|
||||||
|
<path d="M264.909 264.467C264.366 262.443 266.219 260.59 268.243 261.132L272.799 262.353C274.824 262.896 275.502 265.426 274.02 266.909L270.685 270.244C269.203 271.726 266.672 271.048 266.129 269.023L264.909 264.467Z" fill="#4C320C"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_215_188" x="0.764322" y="0" width="576.805" height="576.805" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="2.23568"/>
|
||||||
|
<feGaussianBlur stdDeviation="1.11784"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_215_188"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_215_188" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_i_215_188" x="248.485" y="-19.7266" width="393.038" height="415.794" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="-5.1201" dy="27.8761"/>
|
||||||
|
<feGaussianBlur stdDeviation="22.4643"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 0.713726 0 0 0 0 0.270588 0 0 0 1 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_215_188"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter2_i_215_188" x="-14.2056" y="232.015" width="411.952" height="403.987" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="25.6005" dy="-17.6359"/>
|
||||||
|
<feGaussianBlur stdDeviation="14.8767"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 0.713974 0 0 0 0 0.272498 0 0 0 1 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_215_188"/>
|
||||||
|
</filter>
|
||||||
|
<clipPath id="clip0_215_188">
|
||||||
|
<rect x="3" width="572.333" height="572.333" rx="111.784" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.8 KiB |
3
assets/icons/svg/send.svg
Normal file
3
assets/icons/svg/send.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 12 3.269 3.125A59.769 59.769 0 0 1 21.485 12 59.768 59.768 0 0 1 3.27 20.875L5.999 12Zm0 0h7.5" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 296 B |
@ -1,5 +1,5 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import VoiceSvg from '@/assets/icons/svg/vioce.svg';
|
import SendSvg from '@/assets/icons/svg/send.svg';
|
||||||
import React, { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react';
|
import React, { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Keyboard,
|
Keyboard,
|
||||||
@ -125,9 +125,12 @@ export default function SendMessage(props: Props) {
|
|||||||
/>
|
/>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styles.voiceButton}
|
style={styles.voiceButton}
|
||||||
|
onPress={handleSubmit}
|
||||||
className={`absolute right-0 top-1/2 -translate-y-1/2 `} // 使用绝对定位将按钮放在输入框内右侧
|
className={`absolute right-0 top-1/2 -translate-y-1/2 `} // 使用绝对定位将按钮放在输入框内右侧
|
||||||
>
|
>
|
||||||
<VoiceSvg />
|
<View style={{ transform: [{ rotate: '330deg' }] }}>
|
||||||
|
<SendSvg color={'white'} width={24} height={24} />
|
||||||
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@ -156,6 +159,6 @@ const styles = StyleSheet.create({
|
|||||||
backgroundColor: '#FF9500',
|
backgroundColor: '#FF9500',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginRight: 8, // 添加一点右边距
|
marginRight: 8, // 添加一点
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -11,10 +11,10 @@ const AlbumComponent = ({ setModalVisible, style }: CategoryProps) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, style]}>
|
<View style={[styles.container, style]}>
|
||||||
<TouchableOpacity style={{ flex: 3 }}>
|
<TouchableOpacity style={{ flex: 3, opacity: 0 }}>
|
||||||
<ThemedText style={styles.text}>{t('generalSetting.album', { ns: 'personal' })}</ThemedText>
|
<ThemedText style={styles.text}>{t('generalSetting.album', { ns: 'personal' })}</ThemedText>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity style={{ flex: 3 }}>
|
<TouchableOpacity style={{ flex: 3, opacity: 0 }}>
|
||||||
<ThemedText style={styles.text}>{t('generalSetting.shareProfile', { ns: 'personal' })}</ThemedText>
|
<ThemedText style={styles.text}>{t('generalSetting.shareProfile', { ns: 'personal' })}</ThemedText>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => setModalVisible(true)} style={[styles.text, { flex: 1, alignItems: "center", paddingVertical: 6 }]}>
|
<TouchableOpacity onPress={() => setModalVisible(true)} style={[styles.text, { flex: 1, alignItems: "center", paddingVertical: 6 }]}>
|
||||||
|
|||||||
@ -42,9 +42,10 @@ const PrivacyModal = (props: { modalVisible: boolean, setModalVisible: (visible:
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (type) {
|
||||||
loadArticle();
|
loadArticle();
|
||||||
}, []);
|
}
|
||||||
|
}, [type]);
|
||||||
|
|
||||||
if (!article) {
|
if (!article) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -73,7 +73,7 @@ const UserInfo = (props: UserInfoProps) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (modalVisible) {
|
if (modalVisible) {
|
||||||
getLocation();
|
getLocation();
|
||||||
if (Object.keys(currentLocation).length === 0) {
|
if (currentLocation && Object?.keys(currentLocation)?.length === 0) {
|
||||||
getCurrentLocation();
|
getCurrentLocation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
i18n/locales/en/support.json
Normal file
8
i18n/locales/en/support.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"title": "Support & Help",
|
||||||
|
"description": "If you encounter any issues or have any suggestions, please contact us through the following methods.",
|
||||||
|
"onlineSupport": "Online Support",
|
||||||
|
"emailSupport": "Email Support",
|
||||||
|
"pageTitle": "Support & Help - MemoWake",
|
||||||
|
"tabTitle": "Support"
|
||||||
|
}
|
||||||
8
i18n/locales/zh/support.json
Normal file
8
i18n/locales/zh/support.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"title": "支持与帮助",
|
||||||
|
"description": "如果您在使用中遇到任何问题,或有任何建议,请通过以下方式联系我们。",
|
||||||
|
"onlineSupport": "在线客服",
|
||||||
|
"emailSupport": "邮件联系",
|
||||||
|
"pageTitle": "支持与帮助 - MemoWake",
|
||||||
|
"tabTitle": "支持"
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ import enAdmin from './locales/en/admin.json';
|
|||||||
import enAsk from './locales/en/ask.json';
|
import enAsk from './locales/en/ask.json';
|
||||||
import enCommon from './locales/en/common.json';
|
import enCommon from './locales/en/common.json';
|
||||||
import enDownload from './locales/en/download.json';
|
import enDownload from './locales/en/download.json';
|
||||||
|
import enSupport from './locales/en/support.json';
|
||||||
import enExample from './locales/en/example.json';
|
import enExample from './locales/en/example.json';
|
||||||
import enFairclip from './locales/en/fairclip.json';
|
import enFairclip from './locales/en/fairclip.json';
|
||||||
import enLanding from './locales/en/landing.json';
|
import enLanding from './locales/en/landing.json';
|
||||||
@ -14,6 +15,7 @@ import zhAdmin from './locales/zh/admin.json';
|
|||||||
import zhAsk from './locales/zh/ask.json';
|
import zhAsk from './locales/zh/ask.json';
|
||||||
import zhCommon from './locales/zh/common.json';
|
import zhCommon from './locales/zh/common.json';
|
||||||
import zhDownload from './locales/zh/download.json';
|
import zhDownload from './locales/zh/download.json';
|
||||||
|
import zhSupport from './locales/zh/support.json';
|
||||||
import zhExample from './locales/zh/example.json';
|
import zhExample from './locales/zh/example.json';
|
||||||
import zhFairclip from './locales/zh/fairclip.json';
|
import zhFairclip from './locales/zh/fairclip.json';
|
||||||
import zhLanding from './locales/zh/landing.json';
|
import zhLanding from './locales/zh/landing.json';
|
||||||
@ -27,6 +29,7 @@ const translations = {
|
|||||||
ask: enAsk,
|
ask: enAsk,
|
||||||
common: enCommon,
|
common: enCommon,
|
||||||
download: enDownload,
|
download: enDownload,
|
||||||
|
support: enSupport,
|
||||||
example: enExample,
|
example: enExample,
|
||||||
fairclip: enFairclip,
|
fairclip: enFairclip,
|
||||||
landing: enLanding,
|
landing: enLanding,
|
||||||
@ -39,6 +42,7 @@ const translations = {
|
|||||||
ask: zhAsk,
|
ask: zhAsk,
|
||||||
common: zhCommon,
|
common: zhCommon,
|
||||||
download: zhDownload,
|
download: zhDownload,
|
||||||
|
support: zhSupport,
|
||||||
example: zhExample,
|
example: zhExample,
|
||||||
fairclip: zhFairclip,
|
fairclip: zhFairclip,
|
||||||
landing: zhLanding,
|
landing: zhLanding,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user