Use desktop file

This commit is contained in:
Nicola Benaglia 2025-04-20 13:53:57 +02:00
parent de0f52311e
commit f9cfb12a26
4 changed files with 335 additions and 303 deletions

View File

@ -23,7 +23,7 @@ import {
sortablePinnedAppsAtom, sortablePinnedAppsAtom,
} from '../../atoms/global'; } from '../../atoms/global';
import { useRecoilState, useSetRecoilState } from 'recoil'; import { useRecoilState, useSetRecoilState } from 'recoil';
import { saveToLocalStorage } from './AppsNavBar'; import { saveToLocalStorage } from './AppsNavBarDesktop';
import { ContextMenuPinnedApps } from '../ContextMenuPinnedApps'; import { ContextMenuPinnedApps } from '../ContextMenuPinnedApps';
import LockIcon from '@mui/icons-material/Lock'; import LockIcon from '@mui/icons-material/Lock';
import { useHandlePrivateApps } from './useHandlePrivateApps'; import { useHandlePrivateApps } from './useHandlePrivateApps';

View File

@ -1,7 +1,13 @@
import React, { useState, useRef } from 'react'; import React, { useState, useRef } from 'react';
import { ListItemIcon, Menu, MenuItem, Typography, styled } from '@mui/material'; import {
ListItemIcon,
Menu,
MenuItem,
Typography,
styled,
} from '@mui/material';
import PushPinIcon from '@mui/icons-material/PushPin'; import PushPinIcon from '@mui/icons-material/PushPin';
import { saveToLocalStorage } from './Apps/AppsNavBar'; import { saveToLocalStorage } from './Apps/AppsNavBarDesktop';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { sortablePinnedAppsAtom } from '../atoms/global'; import { sortablePinnedAppsAtom } from '../atoms/global';
@ -28,10 +34,12 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
const maxHoldTimeout = useRef(null); const maxHoldTimeout = useRef(null);
const preventClick = useRef(false); const preventClick = useRef(false);
const startTouchPosition = useRef({ x: 0, y: 0 }); // Track initial touch position const startTouchPosition = useRef({ x: 0, y: 0 }); // Track initial touch position
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom); const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(
sortablePinnedAppsAtom
);
const handleContextMenu = (event) => { const handleContextMenu = (event) => {
if(isMine) return if (isMine) return;
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
preventClick.current = true; preventClick.current = true;
@ -42,7 +50,7 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
}; };
const handleTouchStart = (event) => { const handleTouchStart = (event) => {
if(isMine) return if (isMine) return;
const { clientX, clientY } = event.touches[0]; const { clientX, clientY } = event.touches[0];
startTouchPosition.current = { x: clientX, y: clientY }; startTouchPosition.current = { x: clientX, y: clientY };
@ -64,13 +72,14 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
}; };
const handleTouchMove = (event) => { const handleTouchMove = (event) => {
if(isMine) return if (isMine) return;
const { clientX, clientY } = event.touches[0]; const { clientX, clientY } = event.touches[0];
const { x, y } = startTouchPosition.current; const { x, y } = startTouchPosition.current;
// Determine if the touch has moved beyond a small threshold (e.g., 10px) // Determine if the touch has moved beyond a small threshold (e.g., 10px)
const movedEnough = Math.abs(clientX - x) > 10 || Math.abs(clientY - y) > 10; const movedEnough =
Math.abs(clientX - x) > 10 || Math.abs(clientY - y) > 10;
if (movedEnough) { if (movedEnough) {
clearTimeout(longPressTimeout.current); clearTimeout(longPressTimeout.current);
@ -79,7 +88,7 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
}; };
const handleTouchEnd = (event) => { const handleTouchEnd = (event) => {
if(isMine) return if (isMine) return;
clearTimeout(longPressTimeout.current); clearTimeout(longPressTimeout.current);
clearTimeout(maxHoldTimeout.current); clearTimeout(maxHoldTimeout.current);
@ -91,7 +100,7 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
}; };
const handleClose = (e) => { const handleClose = (e) => {
if(isMine) return if (isMine) return;
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -121,24 +130,45 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
e.stopPropagation(); e.stopPropagation();
}} }}
> >
<MenuItem onClick={(e) => { <MenuItem
onClick={(e) => {
handleClose(e); handleClose(e);
setSortablePinnedApps((prev) => { setSortablePinnedApps((prev) => {
if (app?.isPrivate) { if (app?.isPrivate) {
const updatedApps = prev.filter( const updatedApps = prev.filter(
(item) => !(item?.privateAppProperties?.name === app?.privateAppProperties?.name && item?.privateAppProperties?.service === app?.privateAppProperties?.service && item?.privateAppProperties?.identifier === app?.privateAppProperties?.identifier) (item) =>
!(
item?.privateAppProperties?.name ===
app?.privateAppProperties?.name &&
item?.privateAppProperties?.service ===
app?.privateAppProperties?.service &&
item?.privateAppProperties?.identifier ===
app?.privateAppProperties?.identifier
)
);
saveToLocalStorage(
'ext_saved_settings',
'sortablePinnedApps',
updatedApps
); );
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', updatedApps);
return updatedApps; return updatedApps;
} else { } else {
const updatedApps = prev.filter( const updatedApps = prev.filter(
(item) => !(item?.name === app?.name && item?.service === app?.service) (item) =>
!(
item?.name === app?.name && item?.service === app?.service
)
);
saveToLocalStorage(
'ext_saved_settings',
'sortablePinnedApps',
updatedApps
); );
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', updatedApps);
return updatedApps; return updatedApps;
} }
}); });
}}> }}
>
<ListItemIcon sx={{ minWidth: '32px' }}> <ListItemIcon sx={{ minWidth: '32px' }}>
<PushPinIcon fontSize="small" /> <PushPinIcon fontSize="small" />
</ListItemIcon> </ListItemIcon>

View File

@ -19,7 +19,7 @@ import { SaveIcon } from '../../assets/Icons/SaveIcon';
import { IconWrapper } from '../Desktop/DesktopFooter'; import { IconWrapper } from '../Desktop/DesktopFooter';
import { Spacer } from '../../common/Spacer'; import { Spacer } from '../../common/Spacer';
import { LoadingButton } from '@mui/lab'; import { LoadingButton } from '@mui/lab';
import { saveToLocalStorage } from '../Apps/AppsNavBar'; import { saveToLocalStorage } from '../Apps/AppsNavBarDesktop';
import { decryptData, encryptData } from '../../qortalRequests/get'; import { decryptData, encryptData } from '../../qortalRequests/get';
import { saveFileToDiskGeneric } from '../../utils/generateWallet/generateWallet'; import { saveFileToDiskGeneric } from '../../utils/generateWallet/generateWallet';
import { import {

View File

@ -1,176 +1,173 @@
import React, { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from 'react';
import { saveToLocalStorage } from "../Apps/AppsNavBar"; import { saveToLocalStorage } from '../Apps/AppsNavBarDesktop';
import creationImg from './img/creation.webp' import creationImg from './img/creation.webp';
import dashboardImg from './img/dashboard.webp' import dashboardImg from './img/dashboard.webp';
import groupsImg from './img/groups.webp' import groupsImg from './img/groups.webp';
import importantImg from './img/important.webp' import importantImg from './img/important.webp';
import navigationImg from './img/navigation.webp' import navigationImg from './img/navigation.webp';
import overviewImg from './img/overview.webp' import overviewImg from './img/overview.webp';
import startedImg from './img/started.webp' import startedImg from './img/started.webp';
import obtainingImg from './img/obtaining-qort.jpg' import obtainingImg from './img/obtaining-qort.jpg';
const checkIfGatewayIsOnline = async () => { const checkIfGatewayIsOnline = async () => {
try { try {
const url = `https://ext-node.qortal.link/admin/status`; const url = `https://ext-node.qortal.link/admin/status`;
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
}, },
}); });
const data = await response.json(); const data = await response.json();
if (data?.height) { if (data?.height) {
return true return true;
} }
return false return false;
} catch (error) { } catch (error) {
return false return false;
}
} }
};
export const useHandleTutorials = () => { export const useHandleTutorials = () => {
const [openTutorialModal, setOpenTutorialModal] = useState<any>(null); const [openTutorialModal, setOpenTutorialModal] = useState<any>(null);
const [shownTutorials, setShowTutorials] = useState(null) const [shownTutorials, setShowTutorials] = useState(null);
useEffect(() => { useEffect(() => {
try { try {
const storedData = localStorage.getItem('shown-tutorials'); const storedData = localStorage.getItem('shown-tutorials');
if (storedData) { if (storedData) {
setShowTutorials(JSON.parse(storedData)); setShowTutorials(JSON.parse(storedData));
} else { } else {
setShowTutorials({}) setShowTutorials({});
} }
} catch (error) { } catch (error) {
//error //error
} }
}, []) }, []);
const saveShowTutorial = useCallback((type) => { const saveShowTutorial = useCallback((type) => {
try { try {
setShowTutorials((prev) => { setShowTutorials((prev) => {
return { return {
...(prev || {}), ...(prev || {}),
[type]: true [type]: true,
} };
}) });
saveToLocalStorage('shown-tutorials', type, true) saveToLocalStorage('shown-tutorials', type, true);
} catch (error) { } catch (error) {
//error //error
} }
}, []) }, []);
const showTutorial = useCallback(async (type, isForce) => { const showTutorial = useCallback(
async (type, isForce) => {
try { try {
const isOnline = await checkIfGatewayIsOnline() const isOnline = await checkIfGatewayIsOnline();
if(!isOnline) return if (!isOnline) return;
switch (type) { switch (type) {
case "create-account": case 'create-account':
{ {
if((shownTutorials || {})['create-account'] && !isForce) return if ((shownTutorials || {})['create-account'] && !isForce) return;
saveShowTutorial('create-account') saveShowTutorial('create-account');
setOpenTutorialModal({ setOpenTutorialModal({
title: "Account Creation", title: 'Account Creation',
resource: { resource: {
name: "a-test", name: 'a-test',
service: "VIDEO", service: 'VIDEO',
identifier: "account-creation-hub", identifier: 'account-creation-hub',
poster: creationImg poster: creationImg,
}, },
}); });
} }
break; break;
case "important-information": case 'important-information':
{ {
if((shownTutorials || {})['important-information'] && !isForce) return if ((shownTutorials || {})['important-information'] && !isForce)
saveShowTutorial('important-information') return;
saveShowTutorial('important-information');
setOpenTutorialModal({ setOpenTutorialModal({
title: "Important Information!", title: 'Important Information!',
resource: { resource: {
name: "a-test", name: 'a-test',
service: "VIDEO", service: 'VIDEO',
identifier: "important-information-hub", identifier: 'important-information-hub',
poster: importantImg poster: importantImg,
}, },
}); });
} }
break; break;
case "getting-started": case 'getting-started':
{ {
if((shownTutorials || {})['getting-started'] && !isForce) return if ((shownTutorials || {})['getting-started'] && !isForce) return;
saveShowTutorial('getting-started') saveShowTutorial('getting-started');
setOpenTutorialModal({ setOpenTutorialModal({
multi: [ multi: [
{ {
title: "1. Getting Started", title: '1. Getting Started',
resource: { resource: {
name: "a-test", name: 'a-test',
service: "VIDEO", service: 'VIDEO',
identifier: "getting-started-hub", identifier: 'getting-started-hub',
poster: startedImg poster: startedImg,
}, },
}, },
{ {
title: "2. Overview", title: '2. Overview',
resource: { resource: {
name: "a-test", name: 'a-test',
service: "VIDEO", service: 'VIDEO',
identifier: "overview-hub", identifier: 'overview-hub',
poster: overviewImg poster: overviewImg,
}, },
}, },
{ {
title: "3. Qortal Groups", title: '3. Qortal Groups',
resource: { resource: {
name: "a-test", name: 'a-test',
service: "VIDEO", service: 'VIDEO',
identifier: "groups-hub", identifier: 'groups-hub',
poster: groupsImg poster: groupsImg,
}, },
}, },
{ {
title: "4. Obtaining Qort", title: '4. Obtaining Qort',
resource: { resource: {
name: "a-test", name: 'a-test',
service: "VIDEO", service: 'VIDEO',
identifier: "obtaining-qort", identifier: 'obtaining-qort',
poster: obtainingImg poster: obtainingImg,
}, },
}, },
], ],
}); });
} }
break; break;
case "qapps": case 'qapps':
{ {
if((shownTutorials || {})['qapps'] && !isForce) return if ((shownTutorials || {})['qapps'] && !isForce) return;
saveShowTutorial('qapps') saveShowTutorial('qapps');
setOpenTutorialModal({ setOpenTutorialModal({
multi: [ multi: [
{ {
title: "1. Apps Dashboard", title: '1. Apps Dashboard',
resource: { resource: {
name: "a-test", name: 'a-test',
service: "VIDEO", service: 'VIDEO',
identifier: "apps-dashboard-hub", identifier: 'apps-dashboard-hub',
poster: dashboardImg poster: dashboardImg,
}, },
}, },
{ {
title: "2. Apps Navigation", title: '2. Apps Navigation',
resource: { resource: {
name: "a-test", name: 'a-test',
service: "VIDEO", service: 'VIDEO',
identifier: "apps-navigation-hub", identifier: 'apps-navigation-hub',
poster: navigationImg poster: navigationImg,
},
}, },
}
], ],
}); });
} }
@ -181,12 +178,17 @@ useEffect(()=> {
} catch (error) { } catch (error) {
//error //error
} }
}, [shownTutorials]); },
[shownTutorials]
);
return { return {
showTutorial, showTutorial,
hasSeenGettingStarted: shownTutorials === null ? null : !!(shownTutorials || {})['getting-started'], hasSeenGettingStarted:
shownTutorials === null
? null
: !!(shownTutorials || {})['getting-started'],
openTutorialModal, openTutorialModal,
setOpenTutorialModal, setOpenTutorialModal,
shownTutorialsInitiated: !!shownTutorials shownTutorialsInitiated: !!shownTutorials,
}; };
}; };