-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Desktop: Show notification on import/export using interop service
When importing/exporting items in the desktop app, a giant model layer covers all our screen, and the users are forced to wait until the process is completed. This raised our attention and the need of implementing something that would let the users do their things, while still being able to know about when the process is happening and when it is finished. We though and decided that one possible solution would be using the notyf library, which right now is only used by the TrashNotification component, and show a simple and minimal notification indicating the state of the process, instead of covering the entire screen with a modal layer. We truly believe that this would drastically increase the user experience. Co-authored-by: Henrique Silva <[email protected]>
- Loading branch information
1 parent
f1eeeab
commit 333d610
Showing
7 changed files
with
247 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
packages/app-desktop/gui/InteropNotification/InteropNotification.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { useContext, useMemo } from 'react'; | ||
import { _ } from '@joplin/lib/locale'; | ||
import NotyfContext from '../NotyfContext'; | ||
import useAsyncEffect from '@joplin/lib/hooks/useAsyncEffect'; | ||
import { themeStyle } from '@joplin/lib/theme'; | ||
import { Dispatch } from 'redux'; | ||
import { AppStateInterop } from '../../app.reducer'; | ||
import { NotyfNotification } from 'notyf'; | ||
|
||
interface Props { | ||
interop: AppStateInterop[]; | ||
themeId: number; | ||
dispatch: Dispatch; | ||
} | ||
|
||
export default (props: Props) => { | ||
const notyfContext = useContext(NotyfContext); | ||
|
||
const theme = useMemo(() => { | ||
return themeStyle(props.themeId); | ||
}, [props.themeId]); | ||
|
||
const notyf = useMemo(() => { | ||
const output = notyfContext; | ||
output.options.types = notyfContext.options.types.map(type => { | ||
if (type.type === 'success') { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied | ||
(type.icon as any).color = theme.backgroundColor5; | ||
} else if (type.type === 'error') { | ||
type.background = theme.backgroundColor5; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied | ||
(type.icon as any).color = theme.backgroundColor5; | ||
} else if (type.type === 'loading') { | ||
type.background = theme.backgroundColor5; | ||
} | ||
|
||
return type; | ||
}); | ||
return output; | ||
}, [notyfContext, theme]); | ||
|
||
useAsyncEffect(async (_event) => { | ||
for (const op of props.interop) { | ||
if (op.notification && !op.completed) return; | ||
|
||
let msg = ''; | ||
|
||
if (op.operation === 'export') { | ||
if (op.completed) { | ||
msg = _('Successfully exported to %s.', op.path); | ||
} else { | ||
msg = _('Exporting to "%s" as "%s" format. Please wait...', op.path, op.format); | ||
} | ||
} else { | ||
if (op.completed) { | ||
msg = _('Successfully imported from %s.', op.path); | ||
} else { | ||
msg = _('Importing from "%s" as "%s" format. Please wait...', op.path, op.format); | ||
} | ||
} | ||
|
||
let duration = 0; | ||
let notyfType = 'loading'; | ||
|
||
if (op.completed) { | ||
notyf.dismiss(op.notification); | ||
duration = 6000; | ||
notyfType = 'success'; | ||
} | ||
|
||
const notification: NotyfNotification = notyf.open({ | ||
type: notyfType, | ||
message: `${msg}`, | ||
duration: duration, | ||
dismissible: true, | ||
}); | ||
|
||
props.dispatch({ | ||
type: 'INTEROP_NOTIFICATION_DONE', | ||
operation: op.operation, | ||
path: op.path, | ||
notification: notification, | ||
}); | ||
} | ||
}, [notyf, props.dispatch, props.interop]); | ||
|
||
return <div style={{ display: 'none' }}/>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
body .notyf { | ||
color: var(--joplin-color5); | ||
} | ||
|
||
.notyf__toast { | ||
|
||
> .notyf__wrapper { | ||
|
||
> .notyf__message { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
|
||
> .cancel { | ||
color: var(--joplin-color5); | ||
text-decoration: underline; | ||
display: flex; | ||
align-items: center; | ||
} | ||
|
||
> .cancel::after { | ||
content: '✖'; | ||
margin-left: 8px; /* Adjust the space between text and cross */ | ||
} | ||
} | ||
|
||
> .notyf__icon { | ||
width: 24px; | ||
height: 24px; | ||
|
||
> .notyf__icon--success { | ||
background-color: var(--joplin-color5); | ||
/* Add an icon for success */ | ||
//background-image: url('path-to-success-icon.svg'); | ||
//background-size: cover; | ||
} | ||
|
||
> .notyf__icon--error { | ||
background-color: var(--joplin-color5); | ||
/* Add an icon for error */ | ||
//background-image: url('path-to-error-icon.svg'); | ||
//background-size: cover; | ||
} | ||
|
||
> .notyf__icon--loading { | ||
background-color: var(--joplin-color5); | ||
/* Add an icon for loading */ | ||
//background-image: url('path-to-loading-icon.svg'); | ||
//background-size: cover; | ||
} | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.