319 lines
9.8 KiB
JavaScript
319 lines
9.8 KiB
JavaScript
import {
|
|
View,
|
|
Text,
|
|
FlatList,
|
|
Image as NativeImage,
|
|
ActivityIndicator,
|
|
TouchableOpacity,
|
|
} from "react-native";
|
|
import React, {
|
|
useState,
|
|
useEffect,
|
|
useRef,
|
|
useCallback,
|
|
useContext,
|
|
} from "react";
|
|
import { useTailwind } from "tailwind-rn";
|
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import { ListItem, Button, Icon } from "@rneui/themed";
|
|
import { Image } from "expo-image";
|
|
import Empty from "../../../components/Empty";
|
|
import { get, remove, save } from "../../../utils/storeInfo";
|
|
import { AuthContext } from "../../../App";
|
|
import baseRequest from "../../../utils/baseRequest";
|
|
import { generateSignature } from "../../../utils/crypto";
|
|
import MyModal from "../../../components/MyModal";
|
|
import Toast from "react-native-toast-message";
|
|
|
|
export default function SwitchAccount({ navigation, route }) {
|
|
const blurhash = "LcKUTa%gOYWBYRt6xuoJo~s8V@fk";
|
|
|
|
const tailwind = useTailwind();
|
|
const insets = useSafeAreaInsets();
|
|
|
|
//退出登陆
|
|
const { signIn, signOut } = useContext(AuthContext);
|
|
|
|
const [accountList, setAccountList] = useState([]);
|
|
useEffect(() => {
|
|
//获取所有可切换账号
|
|
async function getAccountList() {
|
|
try {
|
|
const keys = await AsyncStorage.getAllKeys();
|
|
const accountKeys = keys.filter((key) =>
|
|
key.startsWith(`account_list_`)
|
|
);
|
|
const accountListCache = await AsyncStorage.multiGet(accountKeys);
|
|
const jsonParsedAccountList = accountListCache.map((item) => ({
|
|
key: item[0],
|
|
data: JSON.parse(item[1]),
|
|
}));
|
|
//判断当前账号是否登录并将登陆的账号放到第一位
|
|
const account = await get("account");
|
|
const allAccountList = jsonParsedAccountList
|
|
.map((item) => ({
|
|
...item,
|
|
online: item.data.account.user_id === account.user_id,
|
|
}))
|
|
.sort((a, b) => {
|
|
if (!b.data.login_time && !a.data.login_time) return 0;
|
|
if (!a.data.login_time) return 1;
|
|
if (!b.data.login_time) return -1;
|
|
return b.data.login_time - a.data.login_time;
|
|
});
|
|
//删除没有设置密码且不在线的账号
|
|
const _accountList = allAccountList.filter(
|
|
(item) => item.data?.password !== undefined || item.online === true
|
|
);
|
|
setAccountList(_accountList);
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}
|
|
getAccountList();
|
|
}, []);
|
|
|
|
//接口登录
|
|
const signInAccount = async (data) => {
|
|
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
|
|
const base = await baseRequest();
|
|
const signature = await generateSignature({
|
|
mobile_phone: data.mobile_phone,
|
|
region_code: data.region_code,
|
|
password: data.password,
|
|
...base,
|
|
});
|
|
try {
|
|
const _response = await fetch(
|
|
`${apiUrl}/api/login/login_by_pswd?signature=${signature}`,
|
|
{
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
mobile_phone: data.mobile_phone,
|
|
region_code: data.region_code,
|
|
password: data.password,
|
|
...base,
|
|
}),
|
|
}
|
|
);
|
|
const _data = await _response.json();
|
|
if (_data.ret === -1) {
|
|
Toast.show({
|
|
type: "error",
|
|
text1: _data.msg,
|
|
topOffset: 60,
|
|
});
|
|
return;
|
|
}
|
|
//更新登录时间
|
|
await save(`account_list_${data.account.user_id}`, {
|
|
...data,
|
|
login_time: new Date().getTime(),
|
|
});
|
|
signIn(_data, data.mobile_phone_origion, data.region_code);
|
|
setAccountList((pre) =>
|
|
pre.map((item) => ({
|
|
...item,
|
|
online: item.data.account.user_id === data.account.user_id,
|
|
}))
|
|
);
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
};
|
|
|
|
//切换账号
|
|
const [isSwitching, setIsSwitching] = useState(false);
|
|
const [warnModalVisible, setWarnModalVisible] = useState(false);
|
|
const [warnModalData, setWarnModalData] = useState({});
|
|
const switchAccount = async (data) => {
|
|
const onlineAccount = accountList.filter((item) => item.online === true);
|
|
if (onlineAccount[0].data.account.user_id === data.account.user_id) return;
|
|
if (!onlineAccount[0].data?.password) {
|
|
setWarnModalVisible(true);
|
|
setWarnModalData(data);
|
|
return;
|
|
}
|
|
setIsSwitching(true);
|
|
await signInAccount(data);
|
|
setIsSwitching(false);
|
|
};
|
|
|
|
//从验证码登录的账号进行切换账号
|
|
const switchAccountWithPhoneNumLogin = async (data) => {
|
|
setIsSwitching(true);
|
|
const onlineAccount = accountList.filter((item) => item.online === true);
|
|
setAccountList((pre) =>
|
|
pre.filter(
|
|
(item) =>
|
|
item.data.account.user_id !== onlineAccount[0].data.account.user_id
|
|
)
|
|
);
|
|
await signInAccount(data);
|
|
setIsSwitching(false);
|
|
};
|
|
|
|
//删除账号
|
|
const removeAccount = async (key, online) => {
|
|
await remove(key);
|
|
if (online) {
|
|
signOut();
|
|
return;
|
|
}
|
|
setAccountList((pre) => pre.filter((item) => item.key !== key));
|
|
};
|
|
|
|
//账号卡片组件
|
|
const AccountCard = useCallback(
|
|
({ data, listRef }) => {
|
|
return (
|
|
<ListItem.Swipeable
|
|
onPress={() => switchAccount(data.data)}
|
|
bottomDivider
|
|
onSwipeBegin={() => {
|
|
listRef.current.setNativeProps({
|
|
scrollEnabled: false,
|
|
});
|
|
}}
|
|
onSwipeEnd={() => {
|
|
listRef.current.setNativeProps({
|
|
scrollEnabled: true,
|
|
});
|
|
}}
|
|
containerStyle={tailwind("p-0 bg-[#07050A]")}
|
|
rightContent={(reset) => (
|
|
<Button
|
|
title="删除"
|
|
onPress={() => {
|
|
removeAccount(data.key, data.online);
|
|
reset();
|
|
}}
|
|
icon={{ name: "delete", color: "white" }}
|
|
buttonStyle={{ minHeight: "100%", backgroundColor: "red" }}
|
|
titleStyle={tailwind("text-base")}
|
|
/>
|
|
)}
|
|
>
|
|
<View style={tailwind("flex-1")}>
|
|
<View style={tailwind("flex-row py-3")}>
|
|
<Image
|
|
style={tailwind("w-12 h-12 rounded-full")}
|
|
source={data.data.account.avatar.images[0].urls[0]}
|
|
placeholder={blurhash}
|
|
contentFit="cover"
|
|
transition={1000}
|
|
cachePolicy="disk"
|
|
/>
|
|
<View
|
|
style={tailwind(
|
|
"flex flex-col flex-1 ml-2 justify-around items-start"
|
|
)}
|
|
>
|
|
<Text
|
|
style={tailwind("text-base text-white font-medium")}
|
|
numberOfLines={1}
|
|
ellipsizeMode="tail"
|
|
>
|
|
{data.data.account.name}
|
|
</Text>
|
|
<View
|
|
style={tailwind(
|
|
"flex-row items-center py-0.5 px-2 bg-[#FFFFFF1A] rounded-full"
|
|
)}
|
|
>
|
|
<NativeImage
|
|
source={require("../../../assets/icon/12DP/ID.png")}
|
|
/>
|
|
<Text
|
|
style={tailwind("text-white text-xs font-medium ml-0.5")}
|
|
>
|
|
{data.data.account.user_id}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
{data.online && (
|
|
<View style={tailwind("flex justify-center")}>
|
|
<Icon
|
|
type="ionicon"
|
|
name="checkmark"
|
|
size={24}
|
|
color="#27F5B7"
|
|
/>
|
|
</View>
|
|
)}
|
|
</View>
|
|
</View>
|
|
</ListItem.Swipeable>
|
|
);
|
|
},
|
|
[accountList]
|
|
);
|
|
|
|
//删除账号的时候禁用FlatList的滑动
|
|
const accountListRef = useRef(null);
|
|
//单个账号卡片
|
|
const renderItem = ({ item }) => (
|
|
<AccountCard data={item} listRef={accountListRef} />
|
|
);
|
|
|
|
return (
|
|
<View
|
|
style={{
|
|
paddingBottom: insets.bottom,
|
|
paddingLeft: insets.left,
|
|
paddingRight: insets.right,
|
|
...tailwind("flex-1"),
|
|
}}
|
|
>
|
|
<View style={tailwind("px-4 flex-1")}>
|
|
<FlatList
|
|
ref={accountListRef}
|
|
data={accountList}
|
|
renderItem={renderItem}
|
|
initialNumToRender={6}
|
|
ListEmptyComponent={<Empty type="nodata" />}
|
|
ListFooterComponent={
|
|
<TouchableOpacity
|
|
onPress={signOut}
|
|
style={tailwind(
|
|
"flex flex-row items-center justify-center py-2 bg-[#FFFFFF1A] rounded-full mt-4"
|
|
)}
|
|
>
|
|
<Icon type="ionicon" name="add-outline" size={24} color="white" />
|
|
<Text style={tailwind("text-white text-base font-medium ml-1")}>
|
|
添加或注册账号
|
|
</Text>
|
|
</TouchableOpacity>
|
|
}
|
|
/>
|
|
</View>
|
|
{isSwitching && (
|
|
<View
|
|
style={tailwind(
|
|
"absolute flex w-full h-full items-center justify-center"
|
|
)}
|
|
>
|
|
<ActivityIndicator size="large" />
|
|
</View>
|
|
)}
|
|
<MyModal
|
|
visible={warnModalVisible}
|
|
setVisible={setWarnModalVisible}
|
|
title="是否继续切换?"
|
|
content="当前账号为验证码登录,切换账号会导致当前登录状态失效,无法快速切换回此账号,需进行一次密码登录方可保存快速切换账号。"
|
|
cancel={() => {
|
|
setWarnModalVisible(false);
|
|
}}
|
|
confirm={() => {
|
|
setWarnModalVisible(false);
|
|
switchAccountWithPhoneNumLogin(warnModalData);
|
|
}}
|
|
/>
|
|
</View>
|
|
);
|
|
}
|