diff --git a/client/mobile/package.json b/client/mobile/package.json
index 02cb40fe..996ea379 100644
--- a/client/mobile/package.json
+++ b/client/mobile/package.json
@@ -17,6 +17,7 @@
"@formatjs/intl": "^2.6.9",
"@notifee/react-native": "^7.6.1",
"@react-native-async-storage/async-storage": "^1.17.11",
+ "@react-native-community/clipboard": "^1.5.1",
"immer": "^9.0.19",
"lodash": "^4.17.21",
"mini-star": "^2.0.8",
diff --git a/client/mobile/src/Entry.tsx b/client/mobile/src/Entry.tsx
index 9577e4b9..3920f022 100644
--- a/client/mobile/src/Entry.tsx
+++ b/client/mobile/src/Entry.tsx
@@ -1,5 +1,6 @@
-import React, { useState } from 'react';
-import { Alert, ScrollView, StyleSheet, TextInput } from 'react-native';
+import React, { useEffect, useState } from 'react';
+import { Alert, StyleSheet, ScrollView } from 'react-native';
+import Clipboard from '@react-native-community/clipboard';
import { ServerCard } from './components/ServerCard';
import { useServerStore } from './store/server';
import Dialog from 'react-native-ui-lib/dialog';
@@ -9,9 +10,13 @@ import {
Text,
View,
ActionSheet,
+ TextField,
+ TouchableOpacity,
} from 'react-native-ui-lib';
import { isValidUrl } from './lib/utils';
import { translate } from './lib/i18n';
+import { getClientId } from './lib/notifications/getui';
+import { useToast } from './hooks/useToast';
export const Entry: React.FC = React.memo(() => {
const { serverList, selectServer, addServer, removeServer } =
@@ -20,86 +25,112 @@ export const Entry: React.FC = React.memo(() => {
const [serverUrl, setServerUrl] = useState('');
const [loading, setLoading] = useState(false);
const [selectedServer, setSelectedServer] = useState('');
+ const [cid, setCid] = useState('');
+ const { toastEl, showToast } = useToast();
+
+ useEffect(() => {
+ getClientId().then((cid) => {
+ setCid(cid);
+ });
+ }, []);
return (
-
- {serverList.map((serverInfo, i) => {
- return (
- selectServer(serverInfo)}
- onLongPress={() => {
- if (i !== 0) {
- setSelectedServer(serverInfo.url);
- }
- }}
- />
- );
- })}
+
+
+ {serverList.map((serverInfo, i) => {
+ return (
+ selectServer(serverInfo)}
+ onLongPress={() => {
+ if (i !== 0) {
+ setSelectedServer(serverInfo.url);
+ }
+ }}
+ />
+ );
+ })}
- setDialogVisible(true)}
- />
+ setDialogVisible(true)}
+ />
- setSelectedServer('')}
- destructiveButtonIndex={0}
- options={[
- {
- label: translate('core.deleteServer'),
- onPress: () => {
- removeServer(selectedServer);
+ setSelectedServer('')}
+ destructiveButtonIndex={0}
+ options={[
+ {
+ label: translate('core.deleteServer'),
+ onPress: () => {
+ removeServer(selectedServer);
+ },
},
- },
- ]}
- showCancelButton={true}
- />
+ ]}
+ showCancelButton={true}
+ />
+
+
- setLoading(false);
- }}
- />
-
-
-
+
+ {
+ Clipboard.setString(cid);
+ showToast(translate('core.copySuccess'));
+ }}
+ >
+
+ cid: {cid}
+
+
+
+
+ {toastEl}
+
);
});
Entry.displayName = 'Entry';
@@ -109,6 +140,9 @@ const styles = StyleSheet.create({
height: '100%',
padding: 20,
},
+ main: {
+ flex: 1,
+ },
item: {
marginBottom: 8,
},
diff --git a/client/mobile/src/components/ServerCard.tsx b/client/mobile/src/components/ServerCard.tsx
index 39011b72..83c65a5a 100644
--- a/client/mobile/src/components/ServerCard.tsx
+++ b/client/mobile/src/components/ServerCard.tsx
@@ -1,11 +1,6 @@
import React from 'react';
-import {
- StyleProp,
- StyleSheet,
- Text,
- TouchableOpacity,
- ViewStyle,
-} from 'react-native';
+import { StyleProp, StyleSheet, ViewStyle } from 'react-native';
+import { TouchableOpacity, Text } from 'react-native-ui-lib';
interface ServerCardProps {
style?: StyleProp;
@@ -24,10 +19,16 @@ export const ServerCard: React.FC = React.memo((props) => {
>
{props.name}
- {props.url && {props.url}}
+ {props.url && (
+
+ {props.url}
+
+ )}
{props.version && (
- version: {props.version}
+
+ version: {props.version}
+
)}
);
@@ -49,12 +50,12 @@ const styles = StyleSheet.create({
textAlign: 'center',
},
version: {
- color: '#999',
+ // color: '#999',
textAlign: 'center',
fontSize: 10,
},
url: {
- color: '#999',
+ // color: '#999',
textAlign: 'center',
},
});
diff --git a/client/mobile/src/hooks/useToast.tsx b/client/mobile/src/hooks/useToast.tsx
new file mode 100644
index 00000000..5bfbe272
--- /dev/null
+++ b/client/mobile/src/hooks/useToast.tsx
@@ -0,0 +1,28 @@
+import React, { useCallback, useState } from 'react';
+import { Incubator, ToastPresets } from 'react-native-ui-lib';
+
+const { Toast } = Incubator;
+
+export function useToast() {
+ const [visible, setVisible] = useState(false);
+ const [message, setMessage] = useState('');
+
+ const showToast = useCallback((text: string) => {
+ setVisible(true);
+ setMessage(text);
+ }, []);
+
+ return {
+ showToast,
+ toastEl: (
+ setVisible(false)}
+ autoDismiss={3500}
+ swipeable={true}
+ />
+ ),
+ };
+}
diff --git a/client/mobile/src/lib/i18n/translations/en.json b/client/mobile/src/lib/i18n/translations/en.json
index 6111ab24..ff5e209a 100644
--- a/client/mobile/src/lib/i18n/translations/en.json
+++ b/client/mobile/src/lib/i18n/translations/en.json
@@ -4,6 +4,7 @@
"core.deleteServer": "Delete Server",
"core.inputServerUrl": "Input Server Url",
"core.confirm": "Confirm",
+ "core.copySuccess": "Copy Success",
"core.invalidUrl": "Input is not a valid url",
"core.addServerError": "Failed to add server, maybe the address entered is not a Tailchat service address",
"core.foregroundServiceTip": "Continue to keep the service running normally, and may not be able to receive message pushes after closing",
diff --git a/client/mobile/src/lib/i18n/translations/zh.json b/client/mobile/src/lib/i18n/translations/zh.json
index cea2e828..98df03f1 100644
--- a/client/mobile/src/lib/i18n/translations/zh.json
+++ b/client/mobile/src/lib/i18n/translations/zh.json
@@ -4,6 +4,7 @@
"core.deleteServer": "删除服务器",
"core.inputServerUrl": "输入服务器地址",
"core.confirm": "确认",
+ "core.copySuccess": "复制成功",
"core.invalidUrl": "输入不是一个有效的url",
"core.addServerError": "添加服务器失败, 可能输入的地址不是一个Tailchat服务地址",
"core.foregroundServiceTip": "持续保持服务正常运行, 关闭后可能无法正常接受到消息推送",
diff --git a/client/mobile/yarn.lock b/client/mobile/yarn.lock
index dfafbafd..a39dc065 100644
--- a/client/mobile/yarn.lock
+++ b/client/mobile/yarn.lock
@@ -1679,6 +1679,11 @@
prompts "^2.4.0"
semver "^6.3.0"
+"@react-native-community/clipboard@^1.5.1":
+ version "1.5.1"
+ resolved "https://registry.npmmirror.com/@react-native-community/clipboard/-/clipboard-1.5.1.tgz#32abb3ea2eb91ee3f9c5fb1d32d5783253c9fabe"
+ integrity sha512-AHAmrkLEH5UtPaDiRqoULERHh3oNv7Dgs0bTC0hO5Z2GdNokAMPT5w8ci8aMcRemcwbtdHjxChgtjbeA38GBdA==
+
"@react-native-community/eslint-config@^3.2.0":
version "3.2.0"
resolved "https://registry.npmmirror.com/@react-native-community/eslint-config/-/eslint-config-3.2.0.tgz#42f677d5fff385bccf1be1d3b8faa8c086cf998d"