add upgrade notice (#1051)
This commit is contained in:
@@ -58,6 +58,7 @@
|
||||
"@types/rails__actioncable": "^6.1.11",
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/semver": "^7",
|
||||
"@types/unzipper": "^0.10.10",
|
||||
"@types/validator": "^13.12.1",
|
||||
"@types/wavesurfer.js": "^6.0.12",
|
||||
@@ -180,6 +181,7 @@
|
||||
"react-tooltip": "^5.28.0",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rimraf": "^6.0.1",
|
||||
"semver": "^7.6.3",
|
||||
"sequelize": "^6.37.3",
|
||||
"sequelize-typescript": "^2.1.6",
|
||||
"sonner": "^1.5.0",
|
||||
|
||||
@@ -788,5 +788,7 @@
|
||||
"export": "Export",
|
||||
"exportRecordings": "Export recording",
|
||||
"exportRecordingsConfirmation": "Select the highest score of the recordings of each segment to export as a single file.",
|
||||
"exportRecordingsSuccess": "Export recordings successfully"
|
||||
"exportRecordingsSuccess": "Export recordings successfully",
|
||||
"upgrade": "Upgrade",
|
||||
"upgradeNotice": "Enjoy App v{{version}} is available. Please upgrade to the latest version."
|
||||
}
|
||||
|
||||
@@ -788,5 +788,7 @@
|
||||
"export": "导出",
|
||||
"exportRecordings": "导出录音",
|
||||
"exportRecordingsConfirmation": "选择每个段落最高分的录音,导出为单个文件。",
|
||||
"exportRecordingsSuccess": "导出录音成功"
|
||||
"exportRecordingsSuccess": "导出录音成功",
|
||||
"upgrade": "升级",
|
||||
"upgradeNotice": "Enjoy App v{{version}} 已发布。请升级到最新版本。"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ type AppSettingsProviderState = {
|
||||
user: UserType | null;
|
||||
initialized: boolean;
|
||||
version?: string;
|
||||
latestVersion?: string;
|
||||
libraryPath?: string;
|
||||
login?: (user: UserType) => void;
|
||||
logout?: () => void;
|
||||
@@ -54,6 +55,7 @@ export const AppSettingsProvider = ({
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
const [version, setVersion] = useState<string>("");
|
||||
const [latestVersion, setLatestVersion] = useState<string>("");
|
||||
const [apiUrl, setApiUrl] = useState<string>(WEB_API_URL);
|
||||
const [webApi, setWebApi] = useState<Client>(null);
|
||||
const [cable, setCable] = useState<Consumer>();
|
||||
@@ -259,7 +261,7 @@ export const AppSettingsProvider = ({
|
||||
accessToken: user?.accessToken,
|
||||
locale: language,
|
||||
onError: (err) => {
|
||||
if (user.accessToken && err.status == 401) {
|
||||
if (user && user.accessToken && err.status == 401) {
|
||||
setUser({ ...user, accessToken: null });
|
||||
}
|
||||
},
|
||||
@@ -281,6 +283,10 @@ export const AppSettingsProvider = ({
|
||||
webApi.config("ipa_mappings").then((mappings) => {
|
||||
if (mappings) setIpaMappings(mappings);
|
||||
});
|
||||
|
||||
webApi.config("app_version").then((config) => {
|
||||
if (config.version) setLatestVersion(config.version);
|
||||
});
|
||||
}, [webApi]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -316,6 +322,7 @@ export const AppSettingsProvider = ({
|
||||
switchLearningLanguage,
|
||||
EnjoyApp,
|
||||
version,
|
||||
latestVersion,
|
||||
webApi,
|
||||
apiUrl,
|
||||
setApiUrl: setApiUrlHandler,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useContext, useEffect, useState } from "react";
|
||||
import { AppSettingsProviderContext } from "@renderer/context";
|
||||
import { Button } from "@renderer/components/ui";
|
||||
import { t } from "i18next";
|
||||
import semver from "semver";
|
||||
|
||||
export default () => {
|
||||
const [channels, setChannels] = useState<string[]>([
|
||||
@@ -31,6 +32,7 @@ export default () => {
|
||||
return (
|
||||
<div className="relative">
|
||||
<AuthorizationStatusBar />
|
||||
<UpgradeNotice />
|
||||
<div className="max-w-5xl mx-auto px-4 py-6 lg:px-8">
|
||||
<div className="space-y-4">
|
||||
<EnrollmentSegment />
|
||||
@@ -49,12 +51,18 @@ export default () => {
|
||||
|
||||
const AuthorizationStatusBar = () => {
|
||||
const { user, logout } = useContext(AppSettingsProviderContext);
|
||||
if (!user) return null;
|
||||
|
||||
if (!user.accessToken) {
|
||||
return (
|
||||
<div className="bg-red-500 text-white py-2 px-4 h-12 flex items-center sticky top-0">
|
||||
<div className="bg-destructive text-white py-2 px-4 h-10 flex items-center sticky top-0">
|
||||
<span className="text-sm">{t("authorizationExpired")}</span>
|
||||
<Button variant="outline" size="sm" className="ml-2" onClick={logout}>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="ml-2 py-1 px-2 text-xs h-auto w-auto"
|
||||
onClick={logout}
|
||||
>
|
||||
{t("reLogin")}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -63,3 +71,33 @@ const AuthorizationStatusBar = () => {
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const UpgradeNotice = () => {
|
||||
const { version, latestVersion, EnjoyApp } = useContext(
|
||||
AppSettingsProviderContext
|
||||
);
|
||||
if (!latestVersion) return null;
|
||||
|
||||
// compare version with latestVersion by semver
|
||||
if (semver.gte(version, latestVersion)) return null;
|
||||
|
||||
return (
|
||||
<div className="bg-blue-500 text-white py-2 px-4 h-10 flex items-center sticky top-0">
|
||||
<span className="text-sm">
|
||||
{t("upgradeNotice", { version: latestVersion })}
|
||||
</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="ml-2 py-1 px-2 text-xs h-auto w-auto"
|
||||
onClick={() => {
|
||||
EnjoyApp.shell.openExternal(
|
||||
"https://1000h.org/enjoy-app/install.html"
|
||||
);
|
||||
}}
|
||||
>
|
||||
{t("upgrade")}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8322,6 +8322,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/semver@npm:^7":
|
||||
version: 7.5.8
|
||||
resolution: "@types/semver@npm:7.5.8"
|
||||
checksum: 10c0/8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/shimmer@npm:^1.0.2":
|
||||
version: 1.2.0
|
||||
resolution: "@types/shimmer@npm:1.2.0"
|
||||
@@ -12852,6 +12859,7 @@ __metadata:
|
||||
"@types/rails__actioncable": "npm:^6.1.11"
|
||||
"@types/react": "npm:^18.3.5"
|
||||
"@types/react-dom": "npm:^18.3.0"
|
||||
"@types/semver": "npm:^7"
|
||||
"@types/unzipper": "npm:^0.10.10"
|
||||
"@types/validator": "npm:^13.12.1"
|
||||
"@types/wavesurfer.js": "npm:^6.0.12"
|
||||
@@ -12929,6 +12937,7 @@ __metadata:
|
||||
react-tooltip: "npm:^5.28.0"
|
||||
reflect-metadata: "npm:^0.2.2"
|
||||
rimraf: "npm:^6.0.1"
|
||||
semver: "npm:^7.6.3"
|
||||
sequelize: "npm:^6.37.3"
|
||||
sequelize-typescript: "npm:^2.1.6"
|
||||
sonner: "npm:^1.5.0"
|
||||
|
||||
Reference in New Issue
Block a user