diff --git a/client/mobile/package.json b/client/mobile/package.json
index 93f68c4e..8c2f54e2 100644
--- a/client/mobile/package.json
+++ b/client/mobile/package.json
@@ -1,5 +1,5 @@
{
- "name": "Tailchat",
+ "name": "tailchat-mobile",
"version": "0.0.1",
"private": true,
"scripts": {
@@ -10,9 +10,11 @@
"test": "jest"
},
"dependencies": {
+ "immer": "^9.0.19",
"react": "18.2.0",
"react-native": "0.71.2",
- "react-native-webview": "^11.26.1"
+ "react-native-webview": "^11.26.1",
+ "zustand": "^4.3.2"
},
"devDependencies": {
"@babel/core": "^7.20.0",
diff --git a/client/mobile/src/App.tsx b/client/mobile/src/App.tsx
index 56a2fd80..8f3d4fef 100644
--- a/client/mobile/src/App.tsx
+++ b/client/mobile/src/App.tsx
@@ -8,10 +8,15 @@
import React from 'react';
import { SafeAreaView, StatusBar, useColorScheme } from 'react-native';
import { AppMain } from './AppMain';
+import { Entry } from './Entry';
+import { useServerStore } from './store/server';
import { theme } from './theme';
function App(): JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
+ const selectedServerInfo = useServerStore(
+ (state) => state.selectedServerInfo
+ );
const backgroundStyle = {
backgroundColor: isDarkMode ? theme.contentBg.dark : theme.contentBg.light,
@@ -24,7 +29,11 @@ function App(): JSX.Element {
backgroundColor={backgroundStyle.backgroundColor}
/>
-
+ {selectedServerInfo ? (
+
+ ) : (
+
+ )}
);
}
diff --git a/client/mobile/src/AppMain.tsx b/client/mobile/src/AppMain.tsx
index df27b57f..f91d85c4 100644
--- a/client/mobile/src/AppMain.tsx
+++ b/client/mobile/src/AppMain.tsx
@@ -8,10 +8,13 @@ import { WebView } from 'react-native-webview';
* 由webview提供
*/
-export const AppMain: React.FC = React.memo(() => {
+interface Props {
+ host: string;
+}
+export const AppMain: React.FC = React.memo((props) => {
return (
-
+
);
});
diff --git a/client/mobile/src/Entry.tsx b/client/mobile/src/Entry.tsx
new file mode 100644
index 00000000..455324d4
--- /dev/null
+++ b/client/mobile/src/Entry.tsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { Alert, ScrollView, StyleSheet } from 'react-native';
+import { ServerCard } from './components/ServerCard';
+import { useServerStore } from './store/server';
+
+export const Entry: React.FC = React.memo(() => {
+ const { serverList, selectServer } = useServerStore();
+
+ return (
+
+ {serverList.map((serverInfo, i) => {
+ return (
+ selectServer(serverInfo)}
+ />
+ );
+ })}
+
+ Alert.alert('暂不支持')} />
+
+ );
+});
+Entry.displayName = 'Entry';
+
+const styles = StyleSheet.create({
+ root: {
+ height: '100%',
+ padding: 20,
+ },
+ item: {
+ marginBottom: 8,
+ },
+});
diff --git a/client/mobile/src/components/ServerCard.tsx b/client/mobile/src/components/ServerCard.tsx
new file mode 100644
index 00000000..b70e6580
--- /dev/null
+++ b/client/mobile/src/components/ServerCard.tsx
@@ -0,0 +1,48 @@
+import React from 'react';
+import {
+ StyleProp,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ ViewStyle,
+} from 'react-native';
+
+interface ServerCardProps {
+ style?: StyleProp;
+ name: string;
+ url?: string;
+ onPress?: () => void;
+}
+export const ServerCard: React.FC = React.memo((props) => {
+ return (
+
+ {props.name}
+
+ {props.url && {props.url}}
+
+ );
+});
+ServerCard.displayName = 'ServerCard';
+
+const styles = StyleSheet.create({
+ root: {
+ height: 56,
+ padding: 8,
+ backgroundColor: 'white',
+ borderRadius: 4,
+ borderColor: '#ccc',
+ borderWidth: 1,
+ justifyContent: 'center',
+ },
+ name: {
+ fontSize: 16,
+ textAlign: 'center',
+ },
+ url: {
+ color: '#999',
+ textAlign: 'center',
+ },
+});
diff --git a/client/mobile/src/store/server.ts b/client/mobile/src/store/server.ts
new file mode 100644
index 00000000..f5fb8940
--- /dev/null
+++ b/client/mobile/src/store/server.ts
@@ -0,0 +1,41 @@
+import { create } from 'zustand';
+import { immer } from 'zustand/middleware/immer';
+
+interface ServerInfo {
+ name?: string;
+ version?: string;
+ url: string;
+}
+
+interface ServerStoreState {
+ selectedServerInfo: ServerInfo | null;
+ serverList: ServerInfo[];
+ addServer: (url: string) => void;
+ selectServer: (serverInfo: ServerInfo) => void;
+}
+
+const defaultServerList: ServerInfo[] = [
+ {
+ name: 'Tailchat Nightly',
+ url: 'https://nightly.paw.msgbyte.com/',
+ },
+];
+
+export const useServerStore = create()(
+ immer((set) => ({
+ serverList: defaultServerList,
+ selectedServerInfo: null,
+ addServer: (url: string) => {
+ set((state) => {
+ state.serverList.push({
+ url,
+ });
+ });
+ },
+ selectServer: (serverInfo: ServerInfo) => {
+ set({
+ selectedServerInfo: serverInfo,
+ });
+ },
+ }))
+);
diff --git a/client/mobile/yarn.lock b/client/mobile/yarn.lock
index 92547aec..a5cfd632 100644
--- a/client/mobile/yarn.lock
+++ b/client/mobile/yarn.lock
@@ -3687,6 +3687,11 @@ image-size@^0.6.0:
resolved "https://registry.npmmirror.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2"
integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==
+immer@^9.0.19:
+ version "9.0.19"
+ resolved "https://registry.npmmirror.com/immer/-/immer-9.0.19.tgz#67fb97310555690b5f9cd8380d38fc0aabb6b38b"
+ integrity sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==
+
import-fresh@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
@@ -6669,7 +6674,7 @@ urix@^0.1.0:
resolved "https://registry.npmmirror.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==
-use-sync-external-store@^1.0.0:
+use-sync-external-store@1.2.0, use-sync-external-store@^1.0.0:
version "1.2.0"
resolved "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
@@ -6911,3 +6916,10 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+
+zustand@^4.3.2:
+ version "4.3.2"
+ resolved "https://registry.npmmirror.com/zustand/-/zustand-4.3.2.tgz#bb121fcad84c5a569e94bd1a2695e1a93ba85d39"
+ integrity sha512-rd4haDmlwMTVWVqwvgy00ny8rtti/klRoZjFbL/MAcDnmD5qSw/RZc+Vddstdv90M5Lv6RPgWvm1Hivyn0QgJw==
+ dependencies:
+ use-sync-external-store "1.2.0"