From e0392ed2d75e4b9b53500d3ba0ca12c219536a75 Mon Sep 17 00:00:00 2001
From: IZUMI-Zu <274620705z@gmail.com>
Date: Sun, 22 Sep 2024 11:19:07 +0800
Subject: [PATCH] feat: improve scan login logic and ui
---
App.js | 35 +++++++---
CasdoorLoginPage.js | 23 ++++---
EnterAccountDetails.js | 20 +++---
EnterCasdoorSdkConfig.js | 55 ++++++++++++----
Header.js | 134 +++++++++++++++++++++------------------
HomePage.js | 39 ++++++------
ScanLogin.js | 9 +--
SearchBar.js | 38 ++++++++---
api.js | 13 ++++
babel.config.js | 10 ++-
package-lock.json | 23 ++++---
package.json | 2 +-
12 files changed, 256 insertions(+), 145 deletions(-)
diff --git a/App.js b/App.js
index 010fdf8..d8cb384 100644
--- a/App.js
+++ b/App.js
@@ -17,7 +17,8 @@ import {NavigationContainer} from "@react-navigation/native";
import {PaperProvider} from "react-native-paper";
import {SafeAreaView, Text} from "react-native";
import ContentLoader, {Circle, Rect} from "react-content-loader/native";
-import Toast from "react-native-toast-message";
+import {ZoomInDownZoomOutUp, createNotifications} from "react-native-notificated";
+import {GestureHandlerRootView} from "react-native-gesture-handler";
import {useMigrations} from "drizzle-orm/expo-sqlite/migrator";
import Header from "./Header";
@@ -27,6 +28,21 @@ import migrations from "./drizzle/migrations";
const App = () => {
const {success, error} = useMigrations(db, migrations);
+ const {NotificationsProvider} = createNotifications({
+ duration: 800,
+ notificationPosition: "top",
+ animationConfig: ZoomInDownZoomOutUp,
+ isNotch: true,
+ notificationWidth: 350,
+ defaultStylesSettings: {
+ globalConfig: {
+ borderRadius: 15,
+ borderWidth: 2,
+ multiline: 3,
+ defaultIconType: "no-icon",
+ },
+ },
+ });
if (error) {
return (
@@ -59,13 +75,16 @@ const App = () => {
}
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
);
};
export default App;
diff --git a/CasdoorLoginPage.js b/CasdoorLoginPage.js
index effb71f..8094681 100644
--- a/CasdoorLoginPage.js
+++ b/CasdoorLoginPage.js
@@ -16,10 +16,9 @@ import React, {useEffect, useState} from "react";
import {WebView} from "react-native-webview";
import {Platform, SafeAreaView, StatusBar, StyleSheet, Text, TouchableOpacity} from "react-native";
import {Portal} from "react-native-paper";
+import {useNotifications} from "react-native-notificated";
import SDK from "casdoor-react-native-sdk";
import PropTypes from "prop-types";
-import Toast from "react-native-toast-message";
-
import EnterCasdoorSdkConfig from "./EnterCasdoorSdkConfig";
import useStore from "./useStorage";
// import {LogBox} from "react-native";
@@ -31,6 +30,7 @@ const CasdoorLoginPage = ({onWebviewClose}) => {
onWebviewClose: PropTypes.func.isRequired,
};
+ const {notify} = useNotifications();
const [casdoorLoginURL, setCasdoorLoginURL] = useState("");
const [showConfigPage, setShowConfigPage] = useState(true);
@@ -40,6 +40,7 @@ const CasdoorLoginPage = ({onWebviewClose}) => {
redirectPath,
appName,
organizationName,
+ token,
getCasdoorConfig,
setUserInfo,
setToken,
@@ -65,6 +66,12 @@ const CasdoorLoginPage = ({onWebviewClose}) => {
}
}, [serverUrl, clientId, redirectPath, appName, organizationName]);
+ useEffect(() => {
+ if (token) {
+ onWebviewClose();
+ }
+ }, [token]);
+
const onNavigationStateChange = async(navState) => {
const {redirectPath} = getCasdoorConfig();
if (navState.url.startsWith(redirectPath)) {
@@ -77,11 +84,11 @@ const CasdoorLoginPage = ({onWebviewClose}) => {
};
const handleErrorResponse = (error) => {
- Toast.show({
- type: "error",
- text1: "Error",
- text2: error.description,
- autoHide: true,
+ notify("error", {
+ params: {
+ text1: "Error",
+ text2: error.description,
+ },
});
setShowConfigPage(true);
};
@@ -95,7 +102,7 @@ const CasdoorLoginPage = ({onWebviewClose}) => {
onWebviewClose={onWebviewClose}
/>
)}
- {!showConfigPage && casdoorLoginURL !== "" && (
+ {!showConfigPage && casdoorLoginURL !== "" && !token && (
<>
{
@@ -25,6 +25,8 @@ const EnterAccountDetails = ({onClose, onAdd, validateSecret}) => {
validateSecret: PropTypes.func.isRequired,
};
+ const {notify} = useNotifications();
+
const [accountName, setAccountName] = useState("");
const [secretKey, setSecretKey] = useState("");
const [secretError, setSecretError] = useState("");
@@ -51,21 +53,17 @@ const EnterAccountDetails = ({onClose, onAdd, validateSecret}) => {
}
if (accountName.trim() === "" || secretKey.trim() === "") {
- Toast.show({
- type: "error",
- text1: "Error",
- text2: "Please fill in all the fields!",
- autoHide: true,
+ notify("error", {
+ title: "Error",
+ description: "Please fill in all the fields!",
});
return;
}
if (secretError) {
- Toast.show({
- type: "error",
- text1: "Invalid Secret Key",
- text2: "Please check your secret key and try again.",
- autoHide: true,
+ notify("error", {
+ title: "Error",
+ description: "Invalid Secret Key",
});
return;
}
diff --git a/EnterCasdoorSdkConfig.js b/EnterCasdoorSdkConfig.js
index c480602..6f52551 100644
--- a/EnterCasdoorSdkConfig.js
+++ b/EnterCasdoorSdkConfig.js
@@ -15,7 +15,8 @@
import React, {useState} from "react";
import {ScrollView, Text, View} from "react-native";
import {Button, IconButton, Portal, TextInput} from "react-native-paper";
-import Toast from "react-native-toast-message";
+import {useNotifications} from "react-native-notificated";
+import SDK from "casdoor-react-native-sdk";
import DefaultCasdoorSdkConfig from "./DefaultCasdoorSdkConfig";
import PropTypes from "prop-types";
import ScanQRCodeForLogin from "./ScanLogin";
@@ -38,8 +39,13 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
setAppName,
setOrganizationName,
setCasdoorConfig,
+ getCasdoorConfig,
+ setToken,
+ setUserInfo,
} = useStore();
+ const {notify} = useNotifications();
+
const [showScanner, setShowScanner] = useState(false);
const closeConfigPage = () => {
@@ -49,11 +55,11 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
const handleSave = () => {
if (!serverUrl || !clientId || !appName || !organizationName || !redirectPath) {
- Toast.show({
- type: "error",
- text1: "Error",
- text2: "Please fill in all the fields!",
- autoHide: true,
+ notify("error", {
+ params: {
+ title: "Error",
+ description: "Please fill in all the fields!",
+ },
});
return;
}
@@ -66,11 +72,36 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
const handleLogin = (loginInfo) => {
setServerUrl(loginInfo.serverUrl);
- setClientId(loginInfo.clientId);
- setAppName(loginInfo.appName);
- setOrganizationName(loginInfo.organizationName);
- setShowScanner(false);
- onClose();
+ setClientId("");
+ setAppName("");
+ setOrganizationName("");
+
+ const sdk = new SDK(getCasdoorConfig());
+
+ try {
+ const accessToken = loginInfo.accessToken;
+ const userInfo = sdk.JwtDecode(accessToken);
+ setToken(accessToken);
+ setUserInfo(userInfo);
+
+ notify("success", {
+ params: {
+ title: "Success",
+ description: "Logged in successfully!",
+ },
+ });
+
+ setShowScanner(false);
+ onClose();
+ onWebviewClose();
+ } catch (error) {
+ notify("error", {
+ params: {
+ title: "Error in login",
+ description: error,
+ },
+ });
+ }
};
const handleUseDefault = () => {
@@ -147,7 +178,7 @@ const EnterCasdoorSdkConfig = ({onClose, onWebviewClose}) => {
style={[styles.button, styles.outlinedButton]}
labelStyle={styles.outlinedButtonLabel}
>
- Use Casdoor Demo Site
+ Try with Casdoor Demo Site
diff --git a/Header.js b/Header.js
index 90a98d1..d2300e8 100644
--- a/Header.js
+++ b/Header.js
@@ -15,7 +15,8 @@
import * as React from "react";
import {Dimensions, StyleSheet, View} from "react-native";
import {Appbar, Avatar, Menu, Text, TouchableRipple} from "react-native-paper";
-import Toast from "react-native-toast-message";
+import {useNotifications} from "react-native-notificated";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import CasdoorLoginPage, {CasdoorLogout} from "./CasdoorLoginPage";
import useStore from "./useStorage";
import {useAccountSync} from "./useAccountStore";
@@ -24,9 +25,10 @@ const {width} = Dimensions.get("window");
const Header = () => {
const {userInfo, clearAll} = useStore();
- const {syncError, clearSyncError} = useAccountSync();
+ const {isSyncing, syncError, clearSyncError} = useAccountSync();
const [showLoginPage, setShowLoginPage] = React.useState(false);
const [menuVisible, setMenuVisible] = React.useState(false);
+ const {notify} = useNotifications();
const openMenu = () => setMenuVisible(true);
const closeMenu = () => setMenuVisible(false);
@@ -46,32 +48,40 @@ const Header = () => {
};
const handleSyncErrorPress = () => {
- Toast.show({
- type: "error",
- text1: "Sync Error",
- text2: syncError || "An unknown error occurred during synchronization.",
- autoHide: true,
+ notify("error", {
+ params: {
+ title: "Error",
+ description: syncError || "An unknown error occurred during synchronization.",
+ },
});
};
return (
-
-
- {true && syncError && (
-
- )}
-
+
+ Casdoor
+
+ }
+ style={styles.titleWrapper}
/>
+ {userInfo !== null && (
+
+ )}