mirror of
https://github.com/labring/sealos.git
synced 2026-09-19 02:23:07 +08:00
fix: desktop open app & add number of notifications (#3478)
Signed-off-by: zhu jing yang <3161362058@qq.com>
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
.background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: -10;
|
||||
min-width: 100vw;
|
||||
min-height: 100vh;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
import React from 'react';
|
||||
import styles from './index.module.scss';
|
||||
import { Img } from '@chakra-ui/react';
|
||||
|
||||
export const Background = () => {
|
||||
return (
|
||||
<div
|
||||
className={styles.background}
|
||||
style={{
|
||||
backgroundImage: `url(/images/background.png)`
|
||||
}}
|
||||
></div>
|
||||
<Img
|
||||
src="/images/background.png"
|
||||
position={'fixed'}
|
||||
w={'100vw'}
|
||||
h={'100vh'}
|
||||
top={0}
|
||||
bottom={0}
|
||||
right={0}
|
||||
left={0}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,10 +2,16 @@ import Account from '@/components/account';
|
||||
import Notification from '@/components/notification';
|
||||
import useSessionStore from '@/stores/session';
|
||||
import { Box, Flex, Image, useDisclosure } from '@chakra-ui/react';
|
||||
import { useState } from 'react';
|
||||
import Iconfont from '../iconfont';
|
||||
import LangSelect from '../LangSelect';
|
||||
import { i18n } from 'next-i18next';
|
||||
import { useState } from 'react';
|
||||
import LangSelect from '../LangSelect';
|
||||
import Iconfont from '../iconfont';
|
||||
|
||||
enum UserMenuKeys {
|
||||
LangSelect,
|
||||
Notification,
|
||||
Account
|
||||
}
|
||||
|
||||
export default function Index() {
|
||||
const [notificationAmount, setNotificationAmount] = useState(0);
|
||||
@@ -14,40 +20,57 @@ export default function Index() {
|
||||
const switchLangDisclosure = useDisclosure();
|
||||
const userInfo = useSessionStore((state) => state.getSession());
|
||||
if (!userInfo) return null;
|
||||
const buttonList: { click?: () => void, button: JSX.Element, content: JSX.Element }[] = [
|
||||
const buttonList: {
|
||||
click?: () => void;
|
||||
button: JSX.Element;
|
||||
content: JSX.Element;
|
||||
key: UserMenuKeys;
|
||||
}[] = [
|
||||
{
|
||||
button: <Image
|
||||
width={'20px'}
|
||||
height={'20px'}
|
||||
borderRadius="full"
|
||||
src='/images/language.svg'
|
||||
fallbackSrc="/images/sealos.svg"
|
||||
alt="user avator"
|
||||
/>,
|
||||
key: UserMenuKeys.LangSelect,
|
||||
button: (
|
||||
<Image
|
||||
width={'20px'}
|
||||
height={'20px'}
|
||||
borderRadius="full"
|
||||
src="/images/language.svg"
|
||||
fallbackSrc="/images/sealos.svg"
|
||||
alt="user avator"
|
||||
/>
|
||||
),
|
||||
click: () => switchLangDisclosure.onOpen(),
|
||||
content: <LangSelect disclosure={switchLangDisclosure} i18n={i18n} key={'langselect'} />
|
||||
},
|
||||
{
|
||||
button: <Iconfont iconName="icon-notifications" width={20} height={20} color="#24282C"></Iconfont>,
|
||||
key: UserMenuKeys.Notification,
|
||||
button: (
|
||||
<Iconfont iconName="icon-notifications" width={20} height={20} color="#24282C"></Iconfont>
|
||||
),
|
||||
click: () => showDisclosure.onOpen(),
|
||||
content: <Notification
|
||||
key={'notification'}
|
||||
disclosure={showDisclosure}
|
||||
onAmount={(amount) => setNotificationAmount(amount)}
|
||||
/>
|
||||
}, {
|
||||
button: <Image
|
||||
width={'36px'}
|
||||
height={'36px'}
|
||||
borderRadius="full"
|
||||
src={userInfo?.user?.avatar || ''}
|
||||
fallbackSrc="/images/sealos.svg"
|
||||
alt="user avator"
|
||||
/>,
|
||||
content: (
|
||||
<Notification
|
||||
key={'notification'}
|
||||
disclosure={showDisclosure}
|
||||
onAmount={(amount) => setNotificationAmount(amount)}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
key: UserMenuKeys.Account,
|
||||
button: (
|
||||
<Image
|
||||
width={'36px'}
|
||||
height={'36px'}
|
||||
borderRadius="full"
|
||||
src={userInfo?.user?.avatar || ''}
|
||||
fallbackSrc="/images/sealos.svg"
|
||||
alt="user avator"
|
||||
/>
|
||||
),
|
||||
click: () => accountDisclosure.onOpen(),
|
||||
content: <Account disclosure={accountDisclosure} key={'avatar'}/>
|
||||
content: <Account disclosure={accountDisclosure} key={'avatar'} />
|
||||
}
|
||||
]
|
||||
];
|
||||
return (
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
@@ -57,11 +80,11 @@ export default function Index() {
|
||||
cursor={'pointer'}
|
||||
gap={'16px'}
|
||||
>
|
||||
{
|
||||
buttonList.map((item, index) => (<><Flex
|
||||
{buttonList.map((item, index) => (
|
||||
<Flex
|
||||
w="36px"
|
||||
h="36px"
|
||||
key={index}
|
||||
key={item.key}
|
||||
borderRadius={'50%'}
|
||||
background={'rgba(244, 246, 248, 0.7)'}
|
||||
justifyContent={'center'}
|
||||
@@ -69,14 +92,21 @@ export default function Index() {
|
||||
position={'relative'}
|
||||
boxShadow={'0px 1.2px 2.3px rgba(0, 0, 0, 0.2)'}
|
||||
>
|
||||
<Box onClick={item.click}>
|
||||
{item.button}
|
||||
</Box>
|
||||
<Box onClick={item.click}>{item.button}</Box>
|
||||
{item.content}
|
||||
{item.key === UserMenuKeys.Notification && notificationAmount > 0 && (
|
||||
<Box
|
||||
position={'absolute'}
|
||||
top={0}
|
||||
right={0.5}
|
||||
w={'8px'}
|
||||
h={'8px'}
|
||||
borderRadius={'50%'}
|
||||
backgroundColor={'rgba(255, 132, 146, 1)'}
|
||||
></Box>
|
||||
)}
|
||||
</Flex>
|
||||
</>
|
||||
))
|
||||
}
|
||||
))}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ interface IMoreAppsContext {
|
||||
}
|
||||
export const MoreAppsContext = createContext<IMoreAppsContext | null>(null);
|
||||
export const RechargeEnabledContext = createContext<boolean>(false);
|
||||
export default function Home({rechargeEnabled}: {rechargeEnabled: boolean}) {
|
||||
export default function Home({ rechargeEnabled }: { rechargeEnabled: boolean }) {
|
||||
const router = useRouter();
|
||||
const isUpdate = useSessionStore(s => s.newUser)
|
||||
const isUpdate = useSessionStore((s) => s.newUser);
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
const isUserLogin = useSessionStore((s) => s.isUserLogin);
|
||||
const init = useAppStore((state) => state.init);
|
||||
@@ -29,36 +29,37 @@ export default function Home({rechargeEnabled}: {rechargeEnabled: boolean}) {
|
||||
}, [colorMode, toggleColorMode]);
|
||||
const [showMoreApps, setShowMoreApps] = useState(false);
|
||||
useEffect(() => {
|
||||
|
||||
const { query } = router;
|
||||
const is_login = isUserLogin();
|
||||
if (!isUpdate || !is_login) {
|
||||
let param = decodeURIComponent(query?.openapp as string||"")
|
||||
let [openApp, appQuery] = param.split('?',1)
|
||||
if (openApp && typeof appQuery === 'string') setAutoLaunch(openApp, {raw: appQuery})
|
||||
router.replace(destination)
|
||||
let param = decodeURIComponent((query?.openapp as string) || '');
|
||||
const firstQuestionMarkIndex = param.indexOf('?');
|
||||
const openApp = param.substring(0, firstQuestionMarkIndex);
|
||||
const appQuery = param.substring(firstQuestionMarkIndex + 1);
|
||||
if (openApp && typeof appQuery === 'string') setAutoLaunch(openApp, { raw: appQuery });
|
||||
router.replace(destination);
|
||||
} else {
|
||||
init()
|
||||
.then((state) => {
|
||||
let appQuery = ''
|
||||
let appkey = ''
|
||||
if(!state.autolaunch) {
|
||||
let param = decodeURIComponent(query?.openapp as string||"")
|
||||
let [openapp, _appQuery] = param.split('?',2)
|
||||
if (!openapp || typeof _appQuery !== 'string') return
|
||||
appQuery = _appQuery
|
||||
appkey = openapp
|
||||
} else {
|
||||
appQuery = state.autolaunch
|
||||
}
|
||||
const app = state.installedApps.find((item) => item.key === appkey);
|
||||
if (!app) return
|
||||
state
|
||||
.openApp(app, { raw:appQuery })
|
||||
.then(() => {
|
||||
state.cancelAutoLaunch()
|
||||
})
|
||||
})
|
||||
init().then((state) => {
|
||||
let appQuery = '';
|
||||
let appkey = '';
|
||||
if (!state.autolaunch) {
|
||||
let param = decodeURIComponent((query?.openapp as string) || '');
|
||||
const firstQuestionMarkIndex = param.indexOf('?');
|
||||
const openapp = param.substring(0, firstQuestionMarkIndex);
|
||||
const _appQuery = param.substring(firstQuestionMarkIndex + 1);
|
||||
if (!openapp || typeof _appQuery !== 'string') return;
|
||||
appQuery = _appQuery;
|
||||
appkey = openapp;
|
||||
} else {
|
||||
appkey = state.autolaunch;
|
||||
appQuery = state.launchQuery.raw;
|
||||
}
|
||||
const app = state.installedApps.find((item) => item.key === appkey);
|
||||
if (!app) return;
|
||||
state.openApp(app, { raw: appQuery }).then(() => {
|
||||
state.cancelAutoLaunch();
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [router, isUserLogin, init, isUpdate, setAutoLaunch]);
|
||||
|
||||
@@ -69,7 +70,7 @@ export default function Home({rechargeEnabled}: {rechargeEnabled: boolean}) {
|
||||
<DesktopContent />
|
||||
<FloatButton />
|
||||
<MoreApps />
|
||||
</ RechargeEnabledContext.Provider>
|
||||
</RechargeEnabledContext.Provider>
|
||||
</MoreAppsContext.Provider>
|
||||
</Layout>
|
||||
);
|
||||
@@ -77,16 +78,11 @@ export default function Home({rechargeEnabled}: {rechargeEnabled: boolean}) {
|
||||
|
||||
export async function getServerSideProps({ req, res, locales }: any) {
|
||||
const local = req?.cookies?.NEXT_LOCALE || 'en';
|
||||
|
||||
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(
|
||||
local,
|
||||
undefined,
|
||||
null,
|
||||
locales || []
|
||||
)),
|
||||
rechargeEnabled: enableRecharge()
|
||||
...(await serverSideTranslations(local, undefined, null, locales || [])),
|
||||
rechargeEnabled: enableRecharge()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ const useAppStore = create<TOSState>()(
|
||||
currentAppPid: -1,
|
||||
maxZIndex: 0,
|
||||
launchQuery: {},
|
||||
autolaunch: "",
|
||||
autolaunch: '',
|
||||
runner: new AppStateManager([]),
|
||||
init: async () => {
|
||||
const res = await request('/api/desktop/getInstalledApps');
|
||||
@@ -73,7 +73,7 @@ const useAppStore = create<TOSState>()(
|
||||
state.runner.loadApps(state.installedApps.map((app) => app.key));
|
||||
state.maxZIndex = 0;
|
||||
});
|
||||
return get()
|
||||
return get();
|
||||
},
|
||||
// should use pid to close app, but it don't support multi same app process now
|
||||
closeAppById: (pid: number) => {
|
||||
@@ -147,7 +147,7 @@ const useAppStore = create<TOSState>()(
|
||||
const { query, raw } = _query;
|
||||
if (query) _app.data.url = formatUrl(_app.data.url, query);
|
||||
else if (raw) {
|
||||
_app.data.url += `?${raw}`
|
||||
_app.data.url += `?${raw}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,16 +197,18 @@ const useAppStore = create<TOSState>()(
|
||||
state.autolaunch = '';
|
||||
state.launchQuery = {};
|
||||
});
|
||||
},
|
||||
})), {
|
||||
name: 'app',
|
||||
partialize(state) {
|
||||
return {
|
||||
launchQuery: state.launchQuery,
|
||||
autolaunch: state.autolaunch,
|
||||
}
|
||||
},
|
||||
})
|
||||
})),
|
||||
{
|
||||
name: 'app',
|
||||
partialize(state) {
|
||||
return {
|
||||
launchQuery: state.launchQuery,
|
||||
autolaunch: state.autolaunch
|
||||
};
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user