2022-08-31 06:33:37 +05:00
/ *
This file is part of the Notesnook project ( https : //notesnook.com/)
2022-08-30 16:13:11 +05:00
2023-01-16 13:44:52 +05:00
Copyright ( C ) 2023 Streetwriters ( Private ) Limited
2022-08-31 06:33:37 +05:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
2022-09-14 11:19:01 +05:00
import { Text , Flex } from "@theme-ui/components" ;
2023-06-17 11:15:20 +05:00
import Dialog from "../components/dialog" ;
import { getHomeRoute , hardNavigate } from "../navigation" ;
import { appVersion } from "../utils/version" ;
import Config from "../utils/config" ;
2023-07-12 06:51:14 +05:00
2022-07-02 11:33:10 +05:00
import { useEffect } from "react" ;
2023-06-17 11:15:20 +05:00
import { ArrowRight , Checkmark , Icon , Warn } from "../components/icons" ;
2024-07-16 15:04:28 +05:00
import { BaseDialogProps , DialogManager } from "../common/dialog-manager" ;
2022-03-17 12:31:06 +05:00
type CallToAction = {
title : string ;
2022-09-14 11:19:01 +05:00
icon? : Icon ;
2022-03-17 12:31:06 +05:00
action ? : ( ) = > void ;
} ;
type SubFeature = {
title : string ;
2022-09-14 11:19:01 +05:00
icon? : Icon ;
2022-03-17 12:31:06 +05:00
subtitle? : string | JSX . Element ;
} ;
type Feature = {
shouldShow ? : ( ) = > boolean ;
title : string ;
subtitle? : string ;
cta : CallToAction ;
subFeatures? : SubFeature [ ] ;
} ;
2022-04-14 17:33:46 +05:00
export type FeatureKeys = "confirmed" | "highlights" ;
2022-03-17 12:31:06 +05:00
const features : Record < FeatureKeys , Feature > = {
confirmed : {
title : "Email confirmed!" ,
subtitle : "You can now sync your notes to unlimited devices." ,
cta : {
title : "Continue" ,
2022-09-14 11:19:01 +05:00
icon : ArrowRight ,
2022-08-26 16:19:39 +05:00
action : ( ) = > hardNavigate ( getHomeRoute ( ) )
}
2022-03-17 12:31:06 +05:00
} ,
highlights : {
2022-07-04 14:51:47 +05:00
title : appVersion.isBeta
? "Welcome to Notesnook Beta!"
: "✨ Highlights ✨" ,
subtitle : appVersion.isBeta
? ` v ${ appVersion . clean } -beta `
: ` Welcome to v ${ appVersion . clean } ` ,
subFeatures : appVersion.isBeta
? [
{
2022-09-14 11:19:01 +05:00
icon : Warn ,
2022-07-04 14:51:47 +05:00
title : "Notice" ,
subtitle : (
< >
This is the beta version and as such will contain bugs . Things
are expected to break but should be generally stable . Please use
the < Code text = "Report an issue" / > button to report all bugs .
Thank you !
< / >
2022-08-26 16:19:39 +05:00
)
2022-07-04 14:51:47 +05:00
} ,
{
2022-09-14 11:19:01 +05:00
icon : Warn ,
2022-07-04 14:51:47 +05:00
title : "Notice 2" ,
subtitle : (
< >
Switching between beta & amp ; stable versions can cause weird
issues including data loss . It is recommended that you do not
use both simultaneously . You can switch once the beta version
enters stable .
< / >
2022-08-26 16:19:39 +05:00
)
}
2022-07-04 14:51:47 +05:00
]
2024-08-27 16:20:12 +05:00
: [
{
title : "Full offline mode" ,
subtitle :
"You can now download all your attachments upfront so they are always available on your device even without an Internet connection. To enable just go to Settings > Sync and toggle Full Offline Mode."
} ,
{
title : "Backup with attachments" ,
subtitle :
"You can now backup your notes alongwith all your attachments - kind of like a full account snapshot."
} ,
{
title : "Self hosting" ,
subtitle :
"This release also adds initial support for changing server URLs i.e. to connect your own instance of Notesnook. Please note that this is still experimental and may not work as expected."
}
] ,
2022-03-17 12:31:06 +05:00
cta : {
title : "Got it" ,
2022-09-14 11:19:01 +05:00
icon : Checkmark ,
2022-03-17 12:31:06 +05:00
action : ( ) = > {
Config . set ( ` ${ appVersion . numerical } :highlights ` , true ) ;
2022-08-26 16:19:39 +05:00
}
2022-03-17 12:31:06 +05:00
} ,
shouldShow : ( ) = > {
2022-06-08 13:21:34 +05:00
if ( ! features . highlights . subFeatures ? . length ) return false ;
2022-04-14 17:33:46 +05:00
const key = ` ${ appVersion . numerical } :highlights ` ;
const hasShownBefore = Config . get ( key , false ) as boolean ;
2022-07-04 14:51:47 +05:00
const hasShownAny =
appVersion . isBeta || Config . has ( ( k ) = > k . endsWith ( ":highlights" ) ) ;
2022-04-14 17:33:46 +05:00
if ( ! hasShownAny ) Config . set ( key , true ) ;
2022-06-08 13:21:34 +05:00
2023-07-12 06:51:14 +05:00
return hasShownAny && ! IS_TESTING && ! hasShownBefore ;
2022-08-26 16:19:39 +05:00
}
}
2022-03-17 12:31:06 +05:00
} ;
2024-07-16 15:04:28 +05:00
type FeatureDialogProps = BaseDialogProps < boolean > & {
2022-03-17 12:31:06 +05:00
featureName : FeatureKeys ;
} ;
2024-07-16 15:04:28 +05:00
export const FeatureDialog = DialogManager . register ( function FeatureDialog (
props : FeatureDialogProps
) {
2022-07-02 11:33:10 +05:00
const { featureName , onClose } = props ;
2022-03-17 12:31:06 +05:00
const feature = features [ featureName ] ;
2022-07-02 11:33:10 +05:00
useEffect ( ( ) = > {
if ( ! feature || ( feature . shouldShow && ! feature . shouldShow ( ) ) ) {
onClose ( false ) ;
}
} , [ feature , onClose ] ) ;
2022-04-06 02:31:42 +05:00
2022-03-17 12:31:06 +05:00
return (
< Dialog
isOpen = { true }
title = { feature . title }
description = { feature . subtitle }
2023-02-08 14:59:40 +05:00
textAlignment = "center"
2022-03-17 12:31:06 +05:00
positiveButton = { {
text : (
< Flex >
{ feature . cta . icon && (
2023-08-01 12:07:21 +05:00
< feature.cta.icon color = "accent" size = { 16 } sx = { { mr : 1 } } / >
2022-03-17 12:31:06 +05:00
) }
{ feature . cta . title }
< / Flex >
) ,
onClick : ( ) = > {
if ( feature . cta . action ) feature . cta . action ( ) ;
props . onClose ( true ) ;
2022-08-26 16:19:39 +05:00
}
2022-03-17 12:31:06 +05:00
} }
>
2022-08-31 06:33:37 +05:00
< Flex mt = { 2 } sx = { { flexDirection : "column" , overflowY : "auto" } } >
2022-03-17 12:31:06 +05:00
{ feature . subFeatures ? . map ( ( feature ) = > (
< Flex
2022-08-30 16:13:11 +05:00
key = { feature . title }
2022-03-17 12:31:06 +05:00
mb = { 2 }
2023-08-01 12:07:21 +05:00
bg = "var(--background-secondary)"
2022-03-17 12:31:06 +05:00
p = { 2 }
2022-08-31 06:33:37 +05:00
sx = { {
borderRadius : "default" ,
":hover" : { bg : "hover" } ,
flexDirection : "column"
} }
2022-03-17 12:31:06 +05:00
>
2022-08-31 06:33:37 +05:00
< Flex sx = { { alignItems : "center" , justifyContent : "start" } } >
2023-08-01 12:07:21 +05:00
{ feature . icon && < feature.icon size = { 14 } color = "accent" / > }
2022-08-31 06:33:37 +05:00
< Text variant = "subtitle" ml = { 1 } sx = { { fontWeight : "normal" } } >
2022-03-17 12:31:06 +05:00
{ feature . title }
< / Text >
< / Flex >
{ feature . subtitle && (
2023-08-01 12:07:21 +05:00
< Text variant = "subBody" sx = { { fontSize : "body" } } >
2022-03-17 12:31:06 +05:00
{ feature . subtitle }
< / Text >
) }
< / Flex >
) ) }
< / Flex >
< / Dialog >
) ;
2024-07-16 15:04:28 +05:00
} ) ;
2022-03-17 12:31:06 +05:00
type CodeProps = { text : string ; href? : string } ;
export function Code ( props : CodeProps ) {
return (
< Text
as = "code"
sx = { {
bg : "background" ,
2023-08-01 12:07:21 +05:00
color : "paragraph" ,
2022-03-17 12:31:06 +05:00
px : 1 ,
borderRadius : 5 ,
fontFamily : "monospace" ,
fontSize : "subBody" ,
border : "1px solid var(--border)" ,
2022-08-26 16:19:39 +05:00
cursor : props.href ? "pointer" : "unset"
2022-03-17 12:31:06 +05:00
} }
onClick = { ( ) = > {
if ( props . href ) window . open ( props . href , "_target" ) ;
} }
>
{ props . text }
< / Text >
) ;
}