Use desktop file

This commit is contained in:
Nicola Benaglia 2025-04-20 13:53:57 +02:00
parent bf4e58bcfa
commit c4f7d150de
6 changed files with 682 additions and 598 deletions

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from "react";
import React, { useEffect, useMemo, useState } from 'react';
import {
AppCircle,
AppCircleContainer,
@ -19,69 +19,78 @@ import {
AppsLibraryContainer,
AppsParent,
AppsWidthLimiter,
} from "./Apps-styles";
import { Avatar, Box, ButtonBase, InputBase } from "@mui/material";
import { Add } from "@mui/icons-material";
import { getBaseApiReact, isMobile } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
} from './Apps-styles';
import { Avatar, Box, ButtonBase, InputBase } from '@mui/material';
import { Add } from '@mui/icons-material';
import { getBaseApiReact, isMobile } from '../../App';
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
import { Spacer } from "../../common/Spacer";
import { executeEvent } from "../../utils/events";
import { AppRating } from "./AppRating";
import { settingsLocalLastUpdatedAtom, sortablePinnedAppsAtom } from "../../atoms/global";
import { saveToLocalStorage } from "./AppsNavBar";
import { useRecoilState, useSetRecoilState } from "recoil";
import { Spacer } from '../../common/Spacer';
import { executeEvent } from '../../utils/events';
import { AppRating } from './AppRating';
import {
settingsLocalLastUpdatedAtom,
sortablePinnedAppsAtom,
} from '../../atoms/global';
import { saveToLocalStorage } from './AppsNavBarDesktop';
import { useRecoilState, useSetRecoilState } from 'recoil';
export const AppInfo = ({ app, myName }) => {
const isInstalled = app?.status?.status === "READY";
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom);
const isInstalled = app?.status?.status === 'READY';
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(
sortablePinnedAppsAtom
);
const isSelectedAppPinned = !!sortablePinnedApps?.find((item)=> item?.name === app?.name && item?.service === app?.service)
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom);
const isSelectedAppPinned = !!sortablePinnedApps?.find(
(item) => item?.name === app?.name && item?.service === app?.service
);
const setSettingsLocalLastUpdated = useSetRecoilState(
settingsLocalLastUpdatedAtom
);
return (
<AppsLibraryContainer
sx={{
height: !isMobile && "100%",
justifyContent: !isMobile && "flex-start",
alignItems: isMobile && 'center'
height: !isMobile && '100%',
justifyContent: !isMobile && 'flex-start',
alignItems: isMobile && 'center',
}}
>
<Box sx={{
<Box
sx={{
display: 'flex',
flexDirection: 'column',
maxWidth: "500px",
width: '90%'
}}>
maxWidth: '500px',
width: '90%',
}}
>
{!isMobile && <Spacer height="30px" />}
<AppsWidthLimiter>
<AppInfoSnippetContainer>
<AppInfoSnippetLeft
sx={{
flexGrow: 1,
gap: "18px",
gap: '18px',
}}
>
<AppCircleContainer
sx={{
width: "auto",
width: 'auto',
}}
>
<AppCircle
sx={{
border: "none",
height: "100px",
width: "100px",
border: 'none',
height: '100px',
width: '100px',
}}
>
<Avatar
sx={{
height: "43px",
width: "43px",
"& img": {
objectFit: "fill",
height: '43px',
width: '43px',
'& img': {
objectFit: 'fill',
},
}}
alt={app?.name}
@ -91,8 +100,8 @@ export const AppInfo = ({ app, myName }) => {
>
<img
style={{
width: "43px",
height: "auto",
width: '43px',
height: 'auto',
}}
src={LogoSelected}
alt="center-icon"
@ -112,12 +121,14 @@ export const AppInfo = ({ app, myName }) => {
<AppInfoSnippetRight></AppInfoSnippetRight>
</AppInfoSnippetContainer>
<Spacer height="11px" />
<Box sx={{
<Box
sx={{
width: '100%',
display: 'flex',
alignItems: 'center',
gap: '20px'
}}>
gap: '20px',
}}
>
<AppDownloadButton
onClick={() => {
setSortablePinnedApps((prev) => {
@ -126,61 +137,70 @@ export const AppInfo = ({ app, myName }) => {
if (isSelectedAppPinned) {
// Remove the selected app if it is pinned
updatedApps = prev.filter(
(item) => !(item?.name === app?.name && item?.service === app?.service)
(item) =>
!(
item?.name === app?.name &&
item?.service === app?.service
)
);
} else {
// Add the selected app if it is not pinned
updatedApps = [...prev, {
updatedApps = [
...prev,
{
name: app?.name,
service: app?.service,
}];
},
];
}
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', updatedApps)
saveToLocalStorage(
'ext_saved_settings',
'sortablePinnedApps',
updatedApps
);
return updatedApps;
});
setSettingsLocalLastUpdated(Date.now())
setSettingsLocalLastUpdated(Date.now());
}}
sx={{
backgroundColor: "#359ff7ff",
width: "100%",
maxWidth: "320px",
height: "29px",
opacity: isSelectedAppPinned ? 0.6 : 1
backgroundColor: '#359ff7ff',
width: '100%',
maxWidth: '320px',
height: '29px',
opacity: isSelectedAppPinned ? 0.6 : 1,
}}
>
<AppDownloadButtonText>
{!isMobile ? (
<>
{isSelectedAppPinned ? 'Unpin from dashboard' : 'Pin to dashboard'}
{isSelectedAppPinned
? 'Unpin from dashboard'
: 'Pin to dashboard'}
</>
) : (
<>
{isSelectedAppPinned ? 'Unpin' : 'Pin'}
</>
<>{isSelectedAppPinned ? 'Unpin' : 'Pin'}</>
)}
</AppDownloadButtonText>
</AppDownloadButton>
<AppDownloadButton
onClick={() => {
executeEvent("addTab", {
executeEvent('addTab', {
data: app,
});
}}
sx={{
backgroundColor: isInstalled ? "#0091E1" : "#247C0E",
width: "100%",
maxWidth: "320px",
height: "29px",
backgroundColor: isInstalled ? '#0091E1' : '#247C0E',
width: '100%',
maxWidth: '320px',
height: '29px',
}}
>
<AppDownloadButtonText>
{isInstalled ? "Open" : "Download"}
{isInstalled ? 'Open' : 'Download'}
</AppDownloadButtonText>
</AppDownloadButton>
</Box>
</AppsWidthLimiter>
<Spacer height="20px" />
<AppsWidthLimiter>
@ -193,7 +213,7 @@ export const AppInfo = ({ app, myName }) => {
<AppsCategoryInfoLabel>Category:</AppsCategoryInfoLabel>
<Spacer height="4px" />
<AppsCategoryInfoValue>
{app?.metadata?.categoryName || "none"}
{app?.metadata?.categoryName || 'none'}
</AppsCategoryInfoValue>
</AppsCategoryInfoSub>
</AppsCategoryInfo>
@ -202,7 +222,7 @@ export const AppInfo = ({ app, myName }) => {
</AppsWidthLimiter>
<Spacer height="20px" />
<AppsInfoDescription>
{app?.metadata?.description || "No description"}
{app?.metadata?.description || 'No description'}
</AppsInfoDescription>
</Box>
</AppsLibraryContainer>

View File

@ -1,4 +1,4 @@
import React from "react";
import React from 'react';
import {
AppCircle,
AppCircleContainer,
@ -10,43 +10,58 @@ import {
AppInfoSnippetMiddle,
AppInfoSnippetRight,
AppInfoUserName,
} from "./Apps-styles";
import { Avatar, ButtonBase } from "@mui/material";
import { getBaseApiReact, isMobile } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
} from './Apps-styles';
import { Avatar, ButtonBase } from '@mui/material';
import { getBaseApiReact, isMobile } from '../../App';
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
import { Spacer } from "../../common/Spacer";
import { executeEvent } from "../../utils/events";
import { AppRating } from "./AppRating";
import { useRecoilState, useSetRecoilState } from "recoil";
import { settingsLocalLastUpdatedAtom, sortablePinnedAppsAtom } from "../../atoms/global";
import { saveToLocalStorage } from "./AppsNavBar";
import { Spacer } from '../../common/Spacer';
import { executeEvent } from '../../utils/events';
import { AppRating } from './AppRating';
import { useRecoilState, useSetRecoilState } from 'recoil';
import {
settingsLocalLastUpdatedAtom,
sortablePinnedAppsAtom,
} from '../../atoms/global';
import { saveToLocalStorage } from './AppsNavBarDesktop';
export const AppInfoSnippet = ({ app, myName, isFromCategory, parentStyles = {} }) => {
export const AppInfoSnippet = ({
app,
myName,
isFromCategory,
parentStyles = {},
}) => {
const isInstalled = app?.status?.status === 'READY';
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(
sortablePinnedAppsAtom
);
const isInstalled = app?.status?.status === 'READY'
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom);
const isSelectedAppPinned = !!sortablePinnedApps?.find((item)=> item?.name === app?.name && item?.service === app?.service)
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom);
const isSelectedAppPinned = !!sortablePinnedApps?.find(
(item) => item?.name === app?.name && item?.service === app?.service
);
const setSettingsLocalLastUpdated = useSetRecoilState(
settingsLocalLastUpdatedAtom
);
return (
<AppInfoSnippetContainer sx={{
...parentStyles
}}>
<AppInfoSnippetContainer
sx={{
...parentStyles,
}}
>
<AppInfoSnippetLeft>
<ButtonBase
sx={{
height: "80px",
width: "60px",
height: '80px',
width: '60px',
}}
onClick={() => {
if (isFromCategory) {
executeEvent("selectedAppInfoCategory", {
executeEvent('selectedAppInfoCategory', {
data: app,
});
return
return;
}
executeEvent("selectedAppInfo", {
executeEvent('selectedAppInfo', {
data: app,
});
}}
@ -54,16 +69,16 @@ export const AppInfoSnippet = ({ app, myName, isFromCategory, parentStyles = {}
<AppCircleContainer>
<AppCircle
sx={{
border: "none",
border: 'none',
}}
>
<Avatar
sx={{
height: "42px",
width: "42px",
height: '42px',
width: '42px',
'& img': {
objectFit: 'fill',
}
},
}}
alt={app?.name}
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
@ -72,8 +87,8 @@ export const AppInfoSnippet = ({ app, myName, isFromCategory, parentStyles = {}
>
<img
style={{
width: "31px",
height: "auto",
width: '31px',
height: 'auto',
}}
src={LogoSelected}
alt="center-icon"
@ -83,75 +98,92 @@ export const AppInfoSnippet = ({ app, myName, isFromCategory, parentStyles = {}
</AppCircleContainer>
</ButtonBase>
<AppInfoSnippetMiddle>
<ButtonBase onClick={()=> {
<ButtonBase
onClick={() => {
if (isFromCategory) {
executeEvent("selectedAppInfoCategory", {
executeEvent('selectedAppInfoCategory', {
data: app,
});
return
return;
}
executeEvent("selectedAppInfo", {
executeEvent('selectedAppInfo', {
data: app,
});
}}>
<AppInfoAppName >
{app?.metadata?.title || app?.name}
</AppInfoAppName>
}}
>
<AppInfoAppName>{app?.metadata?.title || app?.name}</AppInfoAppName>
</ButtonBase>
<Spacer height="6px" />
<AppInfoUserName>
{ app?.name}
</AppInfoUserName>
<AppInfoUserName>{app?.name}</AppInfoUserName>
<Spacer height="3px" />
<AppRating app={app} myName={myName} />
</AppInfoSnippetMiddle>
</AppInfoSnippetLeft>
<AppInfoSnippetRight sx={{
gap: '10px'
}}>
<AppInfoSnippetRight
sx={{
gap: '10px',
}}
>
{!isMobile && (
<AppDownloadButton onClick={()=> {
<AppDownloadButton
onClick={() => {
setSortablePinnedApps((prev) => {
let updatedApps;
if (isSelectedAppPinned) {
// Remove the selected app if it is pinned
updatedApps = prev.filter(
(item) => !(item?.name === app?.name && item?.service === app?.service)
(item) =>
!(
item?.name === app?.name &&
item?.service === app?.service
)
);
} else {
// Add the selected app if it is not pinned
updatedApps = [...prev, {
updatedApps = [
...prev,
{
name: app?.name,
service: app?.service,
}];
},
];
}
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', updatedApps)
saveToLocalStorage(
'ext_saved_settings',
'sortablePinnedApps',
updatedApps
);
return updatedApps;
});
setSettingsLocalLastUpdated(Date.now())
}} sx={{
setSettingsLocalLastUpdated(Date.now());
}}
sx={{
backgroundColor: '#359ff7ff',
opacity: isSelectedAppPinned ? 0.6 : 1
}}>
<AppDownloadButtonText> {isSelectedAppPinned ? 'Unpin' : 'Pin'}</AppDownloadButtonText>
opacity: isSelectedAppPinned ? 0.6 : 1,
}}
>
<AppDownloadButtonText>
{' '}
{isSelectedAppPinned ? 'Unpin' : 'Pin'}
</AppDownloadButtonText>
</AppDownloadButton>
)}
<AppDownloadButton onClick={()=> {
executeEvent("addTab", {
data: app
})
}} sx={{
<AppDownloadButton
onClick={() => {
executeEvent('addTab', {
data: app,
});
}}
sx={{
backgroundColor: isInstalled ? '#0091E1' : '#247C0E',
}}>
<AppDownloadButtonText>{isInstalled ? 'Open' : 'Download'}</AppDownloadButtonText>
}}
>
<AppDownloadButtonText>
{isInstalled ? 'Open' : 'Download'}
</AppDownloadButtonText>
</AppDownloadButton>
</AppInfoSnippetRight>
</AppInfoSnippetContainer>

View File

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

View File

@ -1,7 +1,13 @@
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 { saveToLocalStorage } from './Apps/AppsNavBar';
import { saveToLocalStorage } from './Apps/AppsNavBarDesktop';
import { useRecoilState } from 'recoil';
import { sortablePinnedAppsAtom } from '../atoms/global';
@ -28,10 +34,12 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
const maxHoldTimeout = useRef(null);
const preventClick = useRef(false);
const startTouchPosition = useRef({ x: 0, y: 0 }); // Track initial touch position
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom);
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(
sortablePinnedAppsAtom
);
const handleContextMenu = (event) => {
if(isMine) return
if (isMine) return;
event.preventDefault();
event.stopPropagation();
preventClick.current = true;
@ -42,7 +50,7 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
};
const handleTouchStart = (event) => {
if(isMine) return
if (isMine) return;
const { clientX, clientY } = event.touches[0];
startTouchPosition.current = { x: clientX, y: clientY };
@ -64,13 +72,14 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
};
const handleTouchMove = (event) => {
if(isMine) return
if (isMine) return;
const { clientX, clientY } = event.touches[0];
const { x, y } = startTouchPosition.current;
// 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) {
clearTimeout(longPressTimeout.current);
@ -79,7 +88,7 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
};
const handleTouchEnd = (event) => {
if(isMine) return
if (isMine) return;
clearTimeout(longPressTimeout.current);
clearTimeout(maxHoldTimeout.current);
@ -91,7 +100,7 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
};
const handleClose = (e) => {
if(isMine) return
if (isMine) return;
e.preventDefault();
e.stopPropagation();
@ -121,24 +130,45 @@ export const ContextMenuPinnedApps = ({ children, app, isMine }) => {
e.stopPropagation();
}}
>
<MenuItem onClick={(e) => {
<MenuItem
onClick={(e) => {
handleClose(e);
setSortablePinnedApps((prev) => {
if (app?.isPrivate) {
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;
} else {
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;
}
});
}}>
}}
>
<ListItemIcon sx={{ minWidth: '32px' }}>
<PushPinIcon fontSize="small" />
</ListItemIcon>

View File

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

View File

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