Clearer way to see if there is an update, more fun tracking

This commit is contained in:
Viktor Rådberg
2024-03-30 14:04:12 +01:00
parent 28c2ff536f
commit 3276dc81fc
16 changed files with 9903 additions and 8982 deletions

View File

@@ -1,5 +1,5 @@
import { Button, Modal, Switch } from '@mui/material';
import { useEffect, useState } from 'react';
import { Modal, Switch } from '@mui/material';
import { useEffect } from 'react';
import { twc } from 'react-twc';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { Cross } from '../../Icons/generated';
@@ -7,76 +7,55 @@ import { PreStartMode } from '../../Types/Settings';
import { ModalWrapper } from './InfoModal';
import { Separator } from './Separator';
import { Paragraph } from './TextComponents';
import { useAnalytics } from '../../Hooks/useAnalytics';
const SettingContainer = twc.div`w-full flex flex-col mb-2`;
const ToggleContainer = twc.div`flex flex-row justify-between items-center -mb-1`;
const Container = twc.div`flex flex-col items-center w-full`;
const Container = twc.div`flex flex-col items-start w-full`;
const Description = twc.p`mr-16 text-xs text-left text-text-secondary`;
const baseGithubReleasesUrl =
'https://github.com/Vikeo/LifeTrinket/releases/tag/';
type SettingsModalProps = {
isOpen: boolean;
closeModal: () => void;
};
export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
const { settings, setSettings, isPWA } = useGlobalSettings();
const [isLatestVersion, setIsLatestVersion] = useState(false);
const [newVersion, setNewVersion] = useState<string | undefined>(undefined);
const { settings, setSettings, isPWA, version } = useGlobalSettings();
const analytics = useAnalytics();
useEffect(() => {
if (!isOpen) {
return;
}
async function checkIfLatestVersion() {
try {
const result = await fetch(
'https://api.github.com/repos/Vikeo/LifeTrinket/releases/latest',
{
headers: {
/* @ts-expect-error is defined in vite.config.ts*/
Authorization: `Bearer ${REPO_READ_ACCESS_TOKEN}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
},
}
);
const data = await result.json();
if (!data.name) {
setNewVersion(undefined);
setIsLatestVersion(false);
return;
}
setNewVersion(data.name);
/* @ts-expect-error is defined in vite.config.ts*/
if (data.name === APP_VERSION) {
setIsLatestVersion(true);
return;
}
setIsLatestVersion(false);
} catch (error) {
console.error('error getting latest version string', error);
}
}
checkIfLatestVersion();
analytics.trackEvent('settings_opened');
version.checkForNewVersion('settings');
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isOpen]);
return (
<Modal
open={isOpen}
onClose={closeModal}
onClose={() => {
analytics.trackEvent('settings_outside_clicked');
closeModal();
}}
className="w-full flex justify-center"
>
<>
<div className="flex justify-center items-center relative w-full max-w-[532px]">
<button
onClick={closeModal}
onClick={() => {
analytics.trackEvent('settings_cross_clicked');
closeModal();
}}
className="flex absolute top-12 right-0 z-10 w-10 h-10 bg-primary-main items-center justify-center rounded-full border-solid border-primary-dark border-2"
>
<Cross size="16px" className="text-text-primary " />
@@ -84,31 +63,71 @@ export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
</div>
<ModalWrapper>
<Container>
<h2 className="text-center text-2xl mb-2"> Settings </h2>
<SettingContainer>
<Paragraph>
{/* @ts-expect-error is defined in vite.config.ts*/}
Current version: {APP_VERSION}{' '}
{isLatestVersion && (
<h2 className="text-center text-2xl mb-2 w-full"> Settings </h2>
<div className="flex flex-col mb-2 w-full">
<div className="text-text-primary flex items-center gap-2">
Current version: {version.installedVersion}{' '}
{version.isLatest && (
<span className="text-sm text-text-secondary">(latest)</span>
)}
</Paragraph>
{!isLatestVersion && newVersion && (
<Paragraph className="text-text-secondary text-lg text-center">
New version ({newVersion}) is available!{' '}
</Paragraph>
<div className="text-xs text-text-primary opacity-75">
(
<a
href={baseGithubReleasesUrl + version.installedVersion}
target="_blank"
className="underline"
onClick={() => {
analytics.trackEvent(
`current_change_log_clicked_v${version.installedVersion}`
);
}}
>
Release notes
</a>
)
</div>
</div>
{!version.isLatest && version.remoteVersion && (
<>
<div className="flex gap-2 items-center mt-2">
<Paragraph className="text-text-secondary">
{version.remoteVersion} available!
</Paragraph>
<div className="text-xs text-text-primary opacity-75">
(
<a
href={baseGithubReleasesUrl + version.remoteVersion}
target="_blank"
className="underline"
onClick={() => {
analytics.trackEvent(
`new_change_log_clicked_v${version.remoteVersion}`
);
}}
>
Release notes
</a>
)
</div>
</div>
<button
className="flex justify-center items-center self-start mt-2 bg-primary-main px-3 py-1 rounded-md"
onClick={() => {
{
analytics.trackEvent(`pressed_update`, {
toVersion: version.remoteVersion,
fromVersion: version.installedVersion,
});
window?.location?.reload();
}
}}
>
<span className="text-sm">Update</span>
<span className="text-xs">&nbsp;(reload app)</span>
</button>
</>
)}
</SettingContainer>
{!isLatestVersion && newVersion && (
<Button
variant="contained"
style={{ marginTop: '0.25rem', marginBottom: '0.25rem' }}
onClick={() => window?.location?.reload()}
>
<span>Update</span>
<span className="text-xs">&nbsp;(reload app)</span>
</Button>
)}
</div>
<Separator height="1px" />
<SettingContainer>
@@ -149,7 +168,7 @@ export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
</SettingContainer>
<SettingContainer>
<div className="flex flex-row justify-between items-center mb-1">
<label htmlFor="pre-start-modes">Pre-Start mode</label>
<label htmlFor="pre-start-modes">Player selection style</label>
<select
name="pre-start-modes"
id="pre-start-modes"
@@ -163,9 +182,11 @@ export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
}}
disabled={!settings.showStartingPlayer}
>
<option value={PreStartMode.None}>None</option>
<option value={PreStartMode.RandomKing}>Random King</option>
<option value={PreStartMode.FingerGame}>Finger Game</option>
<option value={PreStartMode.None}>Instant</option>
<option value={PreStartMode.RandomKing}>Royal Shuffle</option>
<option value={PreStartMode.FingerGame}>
Touch Roulette
</option>
</select>
</div>
<div className="text-xs text-left text-text-secondary">
@@ -175,13 +196,13 @@ export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
{settings.preStartMode === PreStartMode.None && (
<div className="text-xs text-left text-text-secondary mt-1">
<span className="text-text-primary">None:</span> The starting
player will simply be shown.
<span className="text-text-primary">Instant:</span> A random
starting player will simply be shown on start.
</div>
)}
{settings.preStartMode === PreStartMode.RandomKing && (
<div className="text-xs text-left text-text-secondary mt-1">
<span className="text-text-primary">Random King:</span>{' '}
<span className="text-text-primary">Royal Shuffle:</span>{' '}
Randomly pass a crown between all players, press the screen to
stop it. The player who has the crown when it stops gets to
start.
@@ -189,7 +210,7 @@ export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
)}
{settings.preStartMode === PreStartMode.FingerGame && (
<div className="text-xs text-left text-text-secondary mt-1">
<span className="text-text-primary">Finger Game:</span> All
<span className="text-text-primary">Touch Roulette:</span> All
players put a finger on the screen, one will be chosen at
random.
</div>
@@ -234,6 +255,16 @@ export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
enabled.
</Description>
</SettingContainer>
<Separator height="1px" />
<button
className="flex justify-center self-center items-center mt-1 mb-1 bg-primary-main px-3 py-1 rounded-md"
onClick={() => {
analytics.trackEvent('settings_save_clicked');
closeModal();
}}
>
<span className="text-sm">Save and Close</span>
</button>
{!isPWA && (
<>
<Separator height="1px" />
@@ -254,14 +285,6 @@ export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
</>
)}
<Separator height="1px" />
<Button
variant="contained"
onClick={closeModal}
style={{ marginTop: '0.25rem' }}
>
Save and Close
</Button>
</Container>
</ModalWrapper>
</>