diff --git a/.vscode/settings.json b/.vscode/settings.json index 7a73a41b..4090ed0e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,2 +1,6 @@ { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": true + } } \ No newline at end of file diff --git a/public/base.manifest.json b/public/base.manifest.json index 5c8e6760..bd28af6d 100644 --- a/public/base.manifest.json +++ b/public/base.manifest.json @@ -4,5 +4,11 @@ "version": "1.15.10", "chrome_url_overrides": { "newtab": "index.html" + }, + "icons": { + "16": "/logos/logo16.png", + "32": "/logos/logo32.png", + "48": "/logos/logo48.png", + "128": "/logos/logo128.png" } } diff --git a/src/App.js b/src/App.js index 7f78a20c..b078d64d 100644 --- a/src/App.js +++ b/src/App.js @@ -1,16 +1,35 @@ -import { useState, useEffect } from 'react' +import React, { Suspense, useEffect, useLayoutEffect, useState } from 'react' +import 'react-contexify/dist/ReactContexify.css' import 'src/assets/App.css' import { Footer, Header } from 'src/components/Layout' import { BookmarksSidebar } from 'src/features/bookmarks' import { MarketingBanner } from 'src/features/MarketingBanner' -import { ScrollCardsNavigator } from './components/Layout' -import { AppContentLayout } from './components/Layout' -import 'react-contexify/dist/ReactContexify.css' -import { setupAnalytics, trackPageView, setupIdentification } from 'src/lib/analytics' +import { setupAnalytics, setupIdentification, trackPageView } from 'src/lib/analytics' +import { useUserPreferences } from 'src/stores/preferences' +import { diffBetweenTwoDatesInDays } from 'src/utils/DateUtils' +import { AppContentLayout, ScrollCardsNavigator } from './components/Layout' +import { isWebOrExtensionVersion } from './utils/Environment' +import { getAppVersion } from './utils/Os' + +const OnboardingModal = React.lazy(() => + import('src/features/onboarding').then((module) => ({ default: module.OnboardingModal })) +) function App() { const [showSideBar, setShowSideBar] = useState(false) const [showSettings, setShowSettings] = useState(false) + const [showOnboarding, setShowOnboarding] = useState(true) + const { onboardingCompleted, firstSeenDate, markOnboardingAsCompleted } = useUserPreferences() + + useLayoutEffect(() => { + if (!onboardingCompleted && getAppVersion() <= '1.15.9') { + const usageDays = diffBetweenTwoDatesInDays(firstSeenDate, Date.now()) + if (usageDays > 0) { + markOnboardingAsCompleted(null) + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [onboardingCompleted, firstSeenDate]) useEffect(() => { setupAnalytics() @@ -21,7 +40,16 @@ function App() { return ( <> +
+ {!onboardingCompleted && isWebOrExtensionVersion() === 'extension' && ( + + + + )}
{ return ( diff --git a/src/components/Elements/ChipsSet/ChipsSet.tsx b/src/components/Elements/ChipsSet/ChipsSet.tsx index 7efe7973..0e5e9d12 100644 --- a/src/components/Elements/ChipsSet/ChipsSet.tsx +++ b/src/components/Elements/ChipsSet/ChipsSet.tsx @@ -1,5 +1,6 @@ -import { Option } from 'src/types' import { useState } from 'react' +import { Option } from 'src/types' +import './chipset.css' type ChipProps = { option: Option @@ -10,30 +11,66 @@ type ChipProps = { const Chip = ({ option, onSelect, active = false }: ChipProps) => { return ( ) } - +type ChangeAction = 'ADD' | 'REMOVE' type ChipsSetProps = { options: Option[] - defaultValue: Option - onChange: (option: Option) => void + defaultValues?: string[] + canSelectMultiple?: boolean + onChange?: (action: ChangeAction, options: Option[]) => void } -export const ChipsSet = ({ options, onChange, defaultValue }: ChipsSetProps) => { - const [selectedChip, setSelectedChip] = useState