Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nora v3.1.0-stable Minor Update #258

Open
wants to merge 120 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
fd2d137
Updated to v3.1.0-stable.20240602
Sandakan Jun 2, 2024
1a8ca83
add support for symbolic links
Brunight Jun 3, 2024
3b9a878
fix misstype
Brunight Jun 6, 2024
6bc7e74
add try catch block so the function doesn't throw with broken symlinks
Brunight Jun 6, 2024
76a4574
Updated to v3.1.0-stable.20240607
Sandakan Jun 7, 2024
ec922e2
Merge pull request #259 from Brunight/minor-release
Sandakan Jun 7, 2024
3747e95
Updated to v3.1.0-stable.20240615
Sandakan Jun 15, 2024
1fa88a6
Temperorily removed flatpak due to build error
Sandakan Jun 15, 2024
76c6d30
Updated to v3.1.0-stable.20240617
Sandakan Jun 17, 2024
8dcb05a
Merge branch 'master' into minor-release
Sandakan Jun 18, 2024
ce631e5
Fixed Nora not importing/exporting theme data
Sandakan Jun 18, 2024
8fe8b8e
Merge branch 'minor-release' of https://github.com/Sandakan/Nora into…
Sandakan Jun 18, 2024
d191db0
Added file associations .icns files
Sandakan Jun 18, 2024
c2d2a1c
Fixed incorrect file associations .icns paths
Sandakan Jun 18, 2024
c8fb97b
Fixed incorrect file associations .icns paths
Sandakan Jun 18, 2024
6fa818f
Fixed non-library songs not showing in Last.FM
Sandakan Jun 23, 2024
7cd905d
Enabled test and lint workflows
Sandakan Jun 23, 2024
e77aa3b
Added a blurred background to full and mini player
Sandakan Jul 12, 2024
9dec16a
Added new shortcut to open the shortcuts prompt
Sandakan Aug 29, 2024
3910674
Create vi.json
ElectroHeavenVN Aug 30, 2024
a9a1629
Update i18n.ts
ElectroHeavenVN Aug 30, 2024
886c279
Run npm run prettier-write
ElectroHeavenVN Aug 30, 2024
f795e72
added skip lyrics lines functionality to mini and full screen player
Sandakan Sep 1, 2024
b6258b0
Added volume control to full-screen player.
Sandakan Sep 1, 2024
808acbf
Merge remote-tracking branch 'upstream/minor-release' into minor-release
ElectroHeavenVN Sep 1, 2024
47c64b6
Update vi.json
ElectroHeavenVN Sep 1, 2024
5806c9c
Added full translation support for lyrics.
Sandakan Sep 5, 2024
2757dc3
Fixed test fail due to parseLyrics function errors
Sandakan Sep 7, 2024
9f85e6f
Fixed a bug where manually synced lyrics aren't saved to songs.
Sandakan Sep 7, 2024
0519692
Migrated to tanstack-store for state management
Sandakan Sep 17, 2024
312bb07
prettier-write run
Sandakan Sep 17, 2024
8ed3357
Merge pull request #278 from Sandakan/feat-tanstack-store
Sandakan Sep 17, 2024
2528a6b
Merge remote-tracking branch 'upstream/minor-release' into minor-release
ElectroHeavenVN Sep 19, 2024
091c2a0
Update vi.json
ElectroHeavenVN Sep 19, 2024
a006043
Update vi.json
ElectroHeavenVN Sep 19, 2024
db603cf
Fix Discord RPC timestamp and localization
ElectroHeavenVN Sep 19, 2024
6895123
Update App.tsx
ElectroHeavenVN Sep 19, 2024
659d582
Improve Discord Rich Presence
ElectroHeavenVN Sep 22, 2024
265cd7e
lint and prettier-write
ElectroHeavenVN Sep 22, 2024
1b85e76
fix localization
ElectroHeavenVN Sep 22, 2024
1b76135
Update discord.js
ElectroHeavenVN Sep 22, 2024
e998f8c
Update filesystem.ts
ElectroHeavenVN Sep 22, 2024
72321f5
Moved localStorage state to the tanstack store.
Sandakan Sep 23, 2024
adb43c0
add romanization
ElectroHeavenVN Sep 24, 2024
9680740
Merge branch 'romaji' into new-features
ElectroHeavenVN Sep 24, 2024
5f9bf06
add success and error notifications
ElectroHeavenVN Sep 24, 2024
194f331
fix parse lyrics
ElectroHeavenVN Sep 24, 2024
9573596
remove 'by'
ElectroHeavenVN Sep 25, 2024
60d8974
covnert Chinese lyrics, add reset lyrics button
ElectroHeavenVN Sep 25, 2024
373f2b2
convert Korean lyrics
ElectroHeavenVN Sep 25, 2024
8b89fad
Merge remote-tracking branch 'upstream/minor-release' into minor-release
ElectroHeavenVN Sep 25, 2024
af1388a
Merge branch 'minor-release' into new-features
ElectroHeavenVN Sep 25, 2024
bfc17dd
lint and prettier-write
ElectroHeavenVN Sep 25, 2024
ba32af0
Update convertToRomaja.ts
ElectroHeavenVN Sep 25, 2024
68656c9
localize Google Translate message
ElectroHeavenVN Sep 25, 2024
0ebb947
Merge branch 'minor-release' into new-features
ElectroHeavenVN Sep 25, 2024
bc6ea27
Auto translate & convert lyrics
ElectroHeavenVN Sep 26, 2024
fd1c3d3
Update LyricsSettings.tsx
ElectroHeavenVN Sep 26, 2024
ab746e6
Update LyricsContainer.tsx
ElectroHeavenVN Sep 26, 2024
2996724
Update romanizeLyrics.ts
ElectroHeavenVN Sep 26, 2024
bf57340
Update LyricsPage.tsx
ElectroHeavenVN Sep 26, 2024
29d585f
Update LyricsContainer.tsx
ElectroHeavenVN Sep 26, 2024
b3514b0
Added support for viewing app data export progress
Sandakan Sep 29, 2024
9fec7ed
Fixed artist name margin issue in SongInfoPage
Sandakan Oct 1, 2024
477c23f
Merge pull request #277 from ElectroHeavenVN/minor-release
Sandakan Oct 1, 2024
a099204
Added possible fix for devtools theme not changing
Sandakan Oct 1, 2024
94df9cc
convert enhanced lyrics
ElectroHeavenVN Oct 2, 2024
e4a4a5e
Merge remote-tracking branch 'upstream/minor-release' into new-features
ElectroHeavenVN Oct 2, 2024
ed59530
Update LyricLine.tsx
ElectroHeavenVN Oct 2, 2024
71f28b0
Update discordRPC.ts
ElectroHeavenVN Oct 2, 2024
05747a0
fix lyrics conversion
ElectroHeavenVN Oct 2, 2024
bc795f2
Compact lyrics
ElectroHeavenVN Oct 3, 2024
f2a3758
Update LyricLine
ElectroHeavenVN Oct 3, 2024
68b54f4
Update getTranslatedLyrics.ts
ElectroHeavenVN Oct 3, 2024
ca01a4a
Fixed app export not saving artworks correctly.
Sandakan Oct 4, 2024
371d426
fix lyrics apperance
ElectroHeavenVN Oct 5, 2024
1a132dc
fix auto convert/translate lyrics
ElectroHeavenVN Oct 5, 2024
5e37060
Fixed app usage not working in latest Windows
Sandakan Oct 11, 2024
5ec0925
Fixed lyrics not updating right after modifying.
Sandakan Oct 19, 2024
4c53e01
Merge remote-tracking branch 'upstream/minor-release' into new-features
ElectroHeavenVN Oct 26, 2024
14bc1d1
Fixed multiple selections not updating songs.
Sandakan Nov 3, 2024
9c7304a
Fixed incorrect error handling practices.
Sandakan Nov 7, 2024
d6575a2
Fixed event listeners not being detached correctly
Sandakan Nov 7, 2024
2919cc4
Merge remote-tracking branch 'upstream/minor-release' into new-features
ElectroHeavenVN Dec 4, 2024
2dca1de
Update romanized lyrics
ElectroHeavenVN Dec 4, 2024
79346d6
Refactor
ElectroHeavenVN Dec 4, 2024
a5fce0c
Updated app dependencies.
Sandakan Dec 4, 2024
f5f5229
Fixed incompatible peer deps
Sandakan Dec 4, 2024
2accfef
Merge pull request #282 from ElectroHeavenVN/new-features
Sandakan Dec 4, 2024
6b26b0a
Fixed outdated lock file error and lyrics pinyin import error
Sandakan Dec 4, 2024
21de522
Update parseLyrics.test.ts
ElectroHeavenVN Dec 5, 2024
88f7b17
change pinyin library to pinyin-pro
ElectroHeavenVN Dec 9, 2024
c252304
refactor
ElectroHeavenVN Dec 9, 2024
f2c5a37
fix non-Chinese characters in lyrics
ElectroHeavenVN Dec 9, 2024
189c767
Update romanizeLyrics.ts
ElectroHeavenVN Dec 9, 2024
144f4db
Merge pull request #292 from ElectroHeavenVN/new-features
Sandakan Dec 9, 2024
b112e60
Added possible fix for missing sharp dependency in linux
Sandakan Dec 9, 2024
51d13e0
Fixed incorrect command lint command listed in pull_request_template
Sandakan Dec 11, 2024
627e73d
Change Kuroshiro library, fix errors and warnings in the `npm run lin…
ElectroHeavenVN Dec 12, 2024
24e4459
Update LyricsPage.tsx
ElectroHeavenVN Dec 12, 2024
c9c4dac
Merge pull request #293 from ElectroHeavenVN/new-features
Sandakan Dec 12, 2024
25424c8
Added electron-builder asarUnpack entry possibly fix sharp error in l…
Sandakan Dec 12, 2024
dbbe941
Fixed media session metadata not showing
Sandakan Dec 14, 2024
4b5d69d
added relevant configs
Sandakan Dec 15, 2024
b270097
Added possible fix for peer deps conflict when using eslint-v9
Sandakan Dec 15, 2024
b9b9e20
completed eslint migration to v9
Sandakan Dec 24, 2024
0325c0f
Merge pull request #297 from Sandakan/eslint-v9
Sandakan Dec 24, 2024
318fc2c
disabled eslint linting in ci/cd workflow temperorily
Sandakan Dec 24, 2024
0fc4102
updated deps
Sandakan Dec 24, 2024
2cf2cba
Updated deps
Sandakan Dec 27, 2024
ba0c246
Updated tsconfig to target ES2022 and moduleResolution to bundler
Sandakan Dec 27, 2024
7ed644e
Merge pull request #298 from Sandakan/tsconfig-nodenext
Sandakan Dec 27, 2024
9b47363
Completed pino-logger migration
Sandakan Jan 4, 2025
102aaa1
Moved to winston logger
Sandakan Jan 5, 2025
40a2367
Removed incorrect error logic using logger function
Sandakan Jan 5, 2025
d045084
Fixed tests that uses updated logger functions
Sandakan Jan 5, 2025
3c601f5
Added support for saving renderer logs to the log file
Sandakan Jan 14, 2025
6491939
Merge pull request #300 from Sandakan/update-logger
Sandakan Jan 14, 2025
2a12148
Migrated from deprecated registerFileProtocol function
Sandakan Jan 14, 2025
0131096
Reused deprecated registerFileProtocol to debug player error
Sandakan Jan 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added support for viewing app data export progress
- Renamed `delay` property to `duration` in MessageToRendererData type.
- Fixed a bug where app starts with the white splash even though the app is in dark mode.
- Updated hyperlinks to always be underlined.
Sandakan committed Sep 29, 2024
commit b3514b0703d43e081154f708417e173ea9054720
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ module.exports = {
'@typescript-eslint/explicit-function-return-type': 'off',
'import/no-unresolved': 'off',
'import/named': 'off',
'promise/always-return': ['warn', { ignoreLastCallback: true }],
'@typescript-eslint/no-explicit-any': 'off',
'react/no-unescaped-entities': 'off',
'@typescript-eslint/no-unused-vars': 'warn'
9 changes: 7 additions & 2 deletions src/@types/app.d.ts
Original file line number Diff line number Diff line change
@@ -868,9 +868,14 @@ declare global {
| 'ARTWORK_SAVED'
| 'RESYNC_SUCCESSFUL';

interface MessageToRendererData extends Record<string, unknown> {
total?: number;
value?: number;
}

type MessageToRendererProps = {
messageCode: MessageCodes;
data?: Record<string, unknown>;
data?: MessageToRendererData;
};

interface NotificationPanelData {
@@ -881,7 +886,7 @@ declare global {
type NotificationTypes = 'DEFAULT' | 'WITH_PROGRESS_BAR';

interface AppNotification {
delay?: number;
duration?: number;
id: string;
order?: number;
content: ReactNode;
145 changes: 77 additions & 68 deletions src/main/core/exportAppData.ts
Original file line number Diff line number Diff line change
@@ -43,9 +43,68 @@ in these config files.
const exportAppData = async (localStorageData: string) => {
const destinations = await showOpenDialog(DEFAULT_EXPORT_DIALOG_OPTIONS);

log('Started to export app data. Please wait...', undefined, undefined, {
sendToRenderer: { messageCode: 'APPDATA_EXPORT_STARTED' }
});
const operations = [
// SONG DATA
{
filename: 'songs.json',
dataString: JSON.stringify({ songs: getSongsData() })
},
// PALETTE DATA
{
filename: 'palettes.json',
dataString: JSON.stringify({ palettes: getPaletteData() })
},
// BLACKLIST DATA
{
filename: 'blacklist.json',
dataString: JSON.stringify({ blacklists: getBlacklistData() })
},
// ARTIST DATA
{
filename: 'artists.json',
dataString: JSON.stringify({ artists: getArtistsData() })
},
// PLAYLIST DATA
{
filename: 'playlists.json',
dataString: JSON.stringify({ playlists: getPlaylistData() })
},
// ALBUM DATA
{
filename: 'albums.json',
dataString: JSON.stringify({ albums: getAlbumsData() })
},
// GENRE DATA
{
filename: 'genres.json',
dataString: JSON.stringify({ genres: getGenresData() })
},
// USER DATA
{
filename: 'userData.json',
dataString: JSON.stringify({ userData: getUserData() })
},
// LISTENING DATA
{
filename: 'listening_data.json',
dataString: JSON.stringify({ listeningData: getListeningData() })
},
// LOCAL STORAGE DATA
{
filename: 'localStorageData.json',
dataString: localStorageData
},
// WARNING MESSAGE
{
filename: 'IMPORTANT - DO NOT EDIT CONTENTS IN THIS DIRECTORY.txt',
dataString: warningMessage
},
// SONG COVERS
{
filename: 'song_covers',
directory: songCoversFolderPath
}
];

try {
if (Array.isArray(destinations) && destinations.length > 0) {
@@ -57,71 +116,21 @@ const exportAppData = async (localStorageData: string) => {

if (exist) log(`'Nora exports' folder already exists. Will re-write contents of the folder.`);

// SONG DATA
const songData = getSongsData();
const songDataString = JSON.stringify({ songs: songData });

await fs.writeFile(path.join(destination, 'songs.json'), songDataString);

// PALETTE DATA
const paletteData = getPaletteData();
const paletteDataString = JSON.stringify({ palettes: paletteData });

await fs.writeFile(path.join(destination, 'palettes.json'), paletteDataString);

// BLACKLIST DATA
const blacklistData = getBlacklistData();
const blacklistDataString = JSON.stringify({ blacklists: blacklistData });

await fs.writeFile(path.join(destination, 'blacklist.json'), blacklistDataString);

// ARTIST DATA
const artistData = getArtistsData();
const artistDataString = JSON.stringify({ artists: artistData });

await fs.writeFile(path.join(destination, 'artists.json'), artistDataString);

// PLAYLIST DATA
const playlistData = getPlaylistData();
const playlistDataString = JSON.stringify({ playlists: playlistData });

await fs.writeFile(path.join(destination, 'playlists.json'), playlistDataString);

// ALBUM DATA
const albumData = getAlbumsData();
const albumDataString = JSON.stringify({ albums: albumData });

await fs.writeFile(path.join(destination, 'albums.json'), albumDataString);

// GENRE DATA
const genreData = getGenresData();
const genreDataString = JSON.stringify({ genres: genreData });

await fs.writeFile(path.join(destination, 'genres.json'), genreDataString);

// USER DATA
const userData = getUserData();
const userDataString = JSON.stringify({ userData });

await fs.writeFile(path.join(destination, 'userData.json'), userDataString);

// LISTENING DATA
const listeningData = getListeningData();
const listeningDataString = JSON.stringify({ listeningData });

await fs.writeFile(path.join(destination, 'listening_data.json'), listeningDataString);

// LOCAL STORAGE DATA
await fs.writeFile(path.join(destination, 'localStorageData.json'), localStorageData);

// SONG ARTWORKS
await copyDir(songCoversFolderPath, path.join(destination, 'song_covers'));

// WARNING TEXT MESSAGE
await fs.writeFile(
path.join(destination, 'IMPORTANT - DO NOT EDIT CONTENTS IN THIS DIRECTORY.txt'),
warningMessage
);
for (let i = 0; i < operations.length; i++) {
const operation = operations[i];

if (operation.directory) await copyDir(operation.directory, destination);
else if (operation.dataString)
await fs.writeFile(path.join(destination, operation.filename), operation.dataString);
else throw new Error('Invalid operation');

log('Exporting app data. Please wait...', undefined, undefined, {
sendToRenderer: {
messageCode: 'APPDATA_EXPORT_STARTED',
data: { total: operations.length, value: i + 1 }
}
});
}

return log('Exported app data successfully.', undefined, 'INFO', {
sendToRenderer: { messageCode: 'APPDATA_EXPORT_SUCCESS' }
18 changes: 1 addition & 17 deletions src/main/log.ts
Original file line number Diff line number Diff line change
@@ -74,23 +74,7 @@ const log = (
const options: LogOptions = { ...defaultLogOptions, ...logOptions };
const seperator = messageType === 'ERROR' ? '======' : messageType === 'WARN' ? '######' : '';

if (options.sendToRenderer) {
// const rendererMsgOptions = {
// code: (messageType === 'INFO' ? 'INFO' : 'FAILURE') as MessageCodes,
// data: undefined as Object | undefined,
// };

// if (typeof options.sendToRenderer === 'object') {
// const { messageCode, data: rendererData } = options.sendToRenderer;

// if (code) rendererMsgOptions.code = code;
// rendererMsgOptions.data = rendererData;
// }
// if (typeof options.sendToRenderer === 'string')
// rendererMsgOptions.code = options.sendToRenderer;

sendMessageToRenderer(options.sendToRenderer);
}
if (options.sendToRenderer) sendMessageToRenderer(options.sendToRenderer);

if (messageType !== 'INFO') mes = mes.toUpperCase();
const str = `\n[${new Date().toUTCString()}] [${logType}] = ${seperator} ${mes} ${seperator}\n\t${objectToString(
72 changes: 15 additions & 57 deletions src/renderer/src/App.tsx
Original file line number Diff line number Diff line change
@@ -81,8 +81,20 @@ let repetitivePlaybackErrorsCount = 0;
// / / / / / / / /

const updateNetworkStatus = () => window.api.settingsHelpers.networkStatusChange(navigator.onLine);
const syncUserData = () =>
window.api.userData
.getUserData()
.then((res) => {
if (!res) return undefined;

dispatch({ type: 'USER_DATA_CHANGE', data: res });
dispatch({ type: 'APP_THEME_CHANGE', data: res.theme });
return res;
})
.catch((err) => console.error(err));

updateNetworkStatus();
syncUserData();
window.addEventListener('online', updateNetworkStatus);
window.addEventListener('offline', updateNetworkStatus);

@@ -485,16 +497,7 @@ export default function App() {
}, []);

useEffect(() => {
window.api.userData
.getUserData()
.then((res) => {
if (!res) return undefined;

dispatch({ type: 'USER_DATA_CHANGE', data: res });
dispatch({ type: 'APP_THEME_CHANGE', data: res.theme });
return undefined;
})
.catch((err) => console.error(err));
syncUserData();

const handleToggleSongPlayback = () => toggleSongPlayback();
const handlePlaySongFromUnknownSource = (_: unknown, data: AudioPlayerData) =>
@@ -1415,7 +1418,7 @@ export default function App() {
iconName: 'info',
iconClassName: 'material-icons-round-outlined',
id: 'alreadyInCurrentPage',
delay: 2500
duration: 2500
}
]);
},
@@ -1716,7 +1719,7 @@ export default function App() {
addNewNotifications([
{
id: 'songPausedOnDelete',
delay: 7500,
duration: 7500,
content: t('notifications.playbackPausedDueToSongDeletion')
}
]);
@@ -1730,51 +1733,6 @@ export default function App() {
dispatch({ type: 'UP_NEXT_SONG_DATA_CHANGE', data: upNextSongData });
}, []);

// const appContextStateValues: AppStateContextType = useStore(store, (state) => {
// const { currentActiveIndex, isVisible, prompts } = store.state.promptMenuNavigationData;

// const promptMenuData = {
// isVisible,
// prompt: prompts?.at(currentActiveIndex)?.prompt,
// className: prompts?.at(currentActiveIndex)?.className,
// noOfPrompts: prompts.length,
// currentActiveIndex
// };

// tempRef.current = state;

// return {
// isDarkMode: state.isDarkMode,
// contextMenuData: state.contextMenuData,
// promptMenuData,
// currentSongData: {
// ...state.currentSongData,
// duration: player.duration || state.currentSongData.duration
// },
// upNextSongData: store.state.upNextSongData,
// currentlyActivePage:
// store.state.navigationHistory.history[state.navigationHistory.pageHistoryIndex],
// notificationPanelData: state.notificationPanelData,
// userData: state.userData,
// localStorageData: state.localStorage,
// queue: state.localStorage.queue,
// isCurrentSongPlaying: state.player.isCurrentSongPlaying,
// noOfPagesInHistory: state.navigationHistory.history.length - 1,
// pageHistoryIndex: state.navigationHistory.pageHistoryIndex,
// volume: state.player.volume.value,
// isMuted: state.player.volume.isMuted,
// isRepeating: state.player.isRepeating,
// isShuffling: state.player.isShuffling,
// isPlayerStalled: state.player.isPlayerStalled,
// bodyBackgroundImage: state.bodyBackgroundImage,
// isMultipleSelectionEnabled: state.multipleSelectionsData.isEnabled,
// multipleSelectionsData: state.multipleSelectionsData,
// appUpdatesState: state.appUpdatesState,
// equalizerOptions: state.localStorage.equalizerPreset,
// playerType: state.playerType
// };
// });

const appUpdateContextValues: AppUpdateContextType = useMemo(
() => ({
updateUserData,
Original file line number Diff line number Diff line change
@@ -232,7 +232,7 @@ const AlbumInfoPage = () => {
addNewNotifications([
{
id: albumContent.albumData.albumId,
delay: 5000,
duration: 5000,
content: t('notifications.addedToQueue', {
count: albumContent.songsData.length
})
4 changes: 2 additions & 2 deletions src/renderer/src/components/AlbumsPage/Album.tsx
Original file line number Diff line number Diff line change
@@ -130,7 +130,7 @@ export const Album = (props: AlbumProp) => {
addNewNotifications([
{
id: 'newSongsToQueue',
delay: 5000,
duration: 5000,
content: t('notifications.addedToQueue', { count: songs.length })
}
]);
@@ -227,7 +227,7 @@ export const Album = (props: AlbumProp) => {
addNewNotifications([
{
id: 'newSongsToQueue',
delay: 5000,
duration: 5000,
content: t(`notifications.addedToQueue`, {
count: props.songs.length
})
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ const DuplicateArtistsSuggestion = (props: Props) => {
{
content: t('common.artistConflictResolved'),
iconName: 'done',
delay: 5000,
duration: 5000,
id: 'ArtistDuplicateSuggestion'
}
]);
@@ -204,7 +204,7 @@ const DuplicateArtistsSuggestion = (props: Props) => {
id: 'suggestionIgnored',
iconClassName: '!material-icons-round-outlined',
iconName: 'do_not_disturb_on',
delay: 5000,
duration: 5000,
content: t('notifications.suggestionIgnored')
}
]);
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ const SeparateArtistsSuggestion = (props: Props) => {
{
content: t('common.artistConflictResolved'),
iconName: 'done',
delay: 5000,
duration: 5000,
id: 'ArtistDuplicateSuggestion'
}
]);
@@ -186,7 +186,7 @@ const SeparateArtistsSuggestion = (props: Props) => {
id: 'suggestionIgnored',
iconName: 'do_not_disturb_on',
iconClassName: 'material-icons-round-outlined',
delay: 5000,
duration: 5000,
content: t('notifications.suggestionIgnored')
}
]);
4 changes: 2 additions & 2 deletions src/renderer/src/components/ArtistPage/Artist.tsx
Original file line number Diff line number Diff line change
@@ -160,7 +160,7 @@ export const Artist = (props: ArtistProp) => {
return addNewNotifications([
{
id: `${uniqueSongIds.length}AddedToQueueFromMultiSelection`,
delay: 5000,
duration: 5000,
content: t(`notifications.addedToQueue`, {
count: uniqueSongIds.length
})
@@ -172,7 +172,7 @@ export const Artist = (props: ArtistProp) => {
return addNewNotifications([
{
id: 'addSongsToQueue',
delay: 5000,
duration: 5000,
content: t(`notifications.addedToQueue`, {
count: props.songIds.length
})
Original file line number Diff line number Diff line change
@@ -301,7 +301,7 @@ const CurrentQueuePage = () => {
addNewNotifications([
{
id: 'shuffleQueue',
delay: 5000,
duration: 5000,
content: t('currentQueuePage.queueShuffleSuccess'),
iconName: 'shuffle'
}
@@ -319,7 +319,7 @@ const CurrentQueuePage = () => {
addNewNotifications([
{
id: 'clearQueue',
delay: 5000,
duration: 5000,
content: t('currentQueuePage.queueCleared'),
iconName: 'check'
}
Original file line number Diff line number Diff line change
@@ -173,7 +173,7 @@ const GenreInfoPage = () => {
addNewNotifications([
{
id: genreData?.genreId || '',
delay: 5000,
duration: 5000,
content: t('notifications.addedToQueue', {
count: genreSongs.length
})
4 changes: 2 additions & 2 deletions src/renderer/src/components/GenresPage/Genre.tsx
Original file line number Diff line number Diff line change
@@ -143,7 +143,7 @@ const Genre = (props: GenreProp) => {
addNewNotifications([
{
id: 'newSongsToQueue',
delay: 5000,
duration: 5000,
content: t(`notifications.addedToQueue`, {
count: songs.length
})
@@ -202,7 +202,7 @@ const Genre = (props: GenreProp) => {
addNewNotifications([
{
id: 'newSongsToQueue',
delay: 5000,
duration: 5000,
content: t(`notifications.addedToQueue`, {
count: songIds.length
})
2 changes: 1 addition & 1 deletion src/renderer/src/components/HomePage/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -368,7 +368,7 @@ const HomePage = () => {
addNewNotifications([
{
id: Math.random().toString(),
delay: 5 * 60 * 1000,
duration: 5 * 60 * 1000,
content: `This is a notification with a number ${roundTo(Math.random(), 2)}`,
iconName: 'notifications_active',
type: 'WITH_PROGRESS_BAR'
2 changes: 1 addition & 1 deletion src/renderer/src/components/Hyperlink.tsx
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ const Hyperlink = (props: HyperlinkProp) => {

return (
<span
className={`about-link w-fit cursor-pointer font-medium text-font-color-highlight-2 outline-1 outline-offset-1 hover:underline focus:!outline dark:text-dark-font-color-highlight-2 ${className}`}
className={`about-link w-fit cursor-pointer font-medium text-font-color-highlight-2 underline outline-1 outline-offset-1 focus:!outline dark:text-dark-font-color-highlight-2 ${className}`}
title={link}
onClick={openLinkConfirmPrompt}
role="link"
Original file line number Diff line number Diff line change
@@ -166,7 +166,7 @@ const LyricsEditorSavePrompt = (props: Props) => {
return addNewNotifications([
{
id: 'lyricsUpdateSuccessful',
delay: 5000,
duration: 5000,
content: t('lyricsEditorSavePrompt.lyricsUpdateSuccess'),
iconName: 'check'
}
Original file line number Diff line number Diff line change
@@ -103,7 +103,7 @@ const BlacklistFolderConfrimPrompt = (props: { folderPaths: string[]; folderName
addNewNotifications([
{
id: `${folderName}Blacklisted`,
delay: 5000,
duration: 5000,
content: t('blacklistFolderConfirmPrompt.folderBlacklisted', {
count: folderPaths.length
}),
18 changes: 5 additions & 13 deletions src/renderer/src/components/NotificationPanel/Notification.tsx
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ const Notification = (props: AppNotification) => {
const {
id,
content,
delay = 5000,
duration = 5000,
buttons,
icon,
iconName = 'info',
@@ -21,13 +21,11 @@ const Notification = (props: AppNotification) => {

const notificationRef = useRef(null as HTMLDivElement | null);
const notificationTimeoutIdRef = useRef(undefined as NodeJS.Timeout | undefined);
// const [dimensions, setDimensions] = useState({ width: 0, height: 0 });

const notificationPanelStyles: any = {};
// notificationPanelStyles['--loading-bar-width'] = `${dimensions.width - 35}px`;
notificationPanelStyles['--loading-bar-progress'] =
`${(progressBarData.value / progressBarData.total) * 100}%`;
notificationPanelStyles['--notification-duration'] = `${delay}ms`;
notificationPanelStyles['--notification-duration'] = `${duration}ms`;

const removeNotification = useCallback(() => {
const isNotificationAnimationDisabled =
@@ -46,20 +44,17 @@ const Notification = (props: AppNotification) => {
useLayoutEffect(() => {
const notification = notificationRef.current;
if (notification) {
// setDimensions({
// width: notification.offsetWidth,
// height: notification.offsetHeight,
// });
notificationTimeoutIdRef.current = setTimeout(removeNotification, delay);
notificationTimeoutIdRef.current = setTimeout(removeNotification, duration);
}

return () => {
if (notificationTimeoutIdRef.current) clearTimeout(notificationTimeoutIdRef.current);
if (notification?.classList.contains('disappear-to-bottom')) {
clearTimeout(notificationTimeoutIdRef.current);
updateNotifications((currNotifications) => currNotifications.filter((x) => x.id !== id));
}
};
}, [delay, id, removeNotification, updateNotifications]);
}, [duration, id, removeNotification, updateNotifications]);

const notificationIcon = useMemo(() => {
if (icon) return icon;
@@ -138,9 +133,6 @@ const Notification = (props: AppNotification) => {
</div>
)}
</div>
{/* {type === 'WITH_PROGRESS_BAR' && progressBarData && (
<div className="notification-loading-bar absolute bottom-0 left-1/2 h-1 w-[85%] flex-grow -translate-x-1/2 overflow-hidden rounded-sm bg-font-color-highlight/10 before:absolute before:h-1 before:w-[var(--loading-bar-progress,0%)] before:rounded-sm before:bg-font-color-highlight/50 before:content-[''] dark:bg-dark-font-color-highlight/20 dark:before:bg-dark-font-color-highlight" />
)} */}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ const NotificationPanel = () => {
return notificationData.map((data) => {
const {
content,
delay,
duration,
id,
buttons,
icon,
@@ -37,7 +37,7 @@ const NotificationPanel = () => {
icon={icon}
iconName={iconName}
iconClassName={iconClassName}
delay={delay}
duration={duration}
order={order}
type={type}
progressBarData={progressBarData}
Original file line number Diff line number Diff line change
@@ -144,7 +144,7 @@ const PlaylistInfoPage = () => {
addNewNotifications([
{
id: 'queueCleared',
delay: 5000,
duration: 5000,
content: t('settingsPage.songHistoryDeletionSuccess')
}
])
@@ -163,7 +163,7 @@ const PlaylistInfoPage = () => {
addNewNotifications([
{
id: `addedToQueue`,
delay: 5000,
duration: 5000,
content: t('notifications.addedToQueue', {
count: validSongIds.length
})
@@ -297,7 +297,7 @@ const PlaylistInfoPage = () => {
addNewNotifications([
{
id: `${item.songId}Removed`,
delay: 5000,
duration: 5000,
content: t('playlistsPage.removeSongFromPlaylistSuccess', {
title: item.title,
playlistName: playlistData.name
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ const ConfirmDeletePlaylistsPrompt = (props: ConfirmDeletePlaylistProp) => {
return addNewNotifications([
{
id: `playlistsDeleted`,
delay: 5000,
duration: 5000,
content: t('confirmDeletePlaylistsPrompt.playlistsDeletedWithCount', {
count: playlistIds.length
})
Original file line number Diff line number Diff line change
@@ -35,15 +35,15 @@ const NewPlaylistPrompt = (props: NewPlaylistPromptProp) => {
addNewNotifications([
{
id: 'playlistCreated',
delay: 5000,
duration: 5000,
content: t('newPlaylistPrompt.addPlaylistSuccess')
}
]);
} else {
addNewNotifications([
{
id: 'playlistCreateFailed',
delay: 5000,
duration: 5000,
// eslint-disable-next-line react/jsx-no-useless-fragment
content: <>{res.message}</>
}
@@ -54,7 +54,7 @@ const NewPlaylistPrompt = (props: NewPlaylistPromptProp) => {
addNewNotifications([
{
id: 'EmptyPlaylistName',
delay: 5000,
duration: 5000,
content: t('newPlaylistPrompt.playlistNameEmpty')
}
]);
8 changes: 4 additions & 4 deletions src/renderer/src/components/PlaylistsPage/Playlist.tsx
Original file line number Diff line number Diff line change
@@ -109,7 +109,7 @@ export const Playlist = (props: PlaylistProp) => {
return addNewNotifications([
{
id: `${songIds.length}AddedToQueueFromMultiSelection`,
delay: 5000,
duration: 5000,
content: t(`notifications.addedToQueue`, {
count: songIds.length
})
@@ -150,7 +150,7 @@ export const Playlist = (props: PlaylistProp) => {
addNewNotifications([
{
id: 'newSongsToQueue',
delay: 5000,
duration: 5000,
content: t(`notifications.addedToQueue`, {
count: songs.length
})
@@ -201,7 +201,7 @@ export const Playlist = (props: PlaylistProp) => {
addNewNotifications([
{
id: 'newSongsToQueue',
delay: 5000,
duration: 5000,
content: t(`notifications.addedToQueue`, {
count: props.songs.length
})
@@ -236,7 +236,7 @@ export const Playlist = (props: PlaylistProp) => {
{
content: t('playlist.playlistArtworkUpdateSuccess'),
icon: <span className="material-icons-round">done</span>,
delay: 5000,
duration: 5000,
id: 'PlaylistArtworkUpdateSuccessful'
}
]);
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ const MostRelevantSearchResultsContainer = (props: Props) => {
addNewNotifications([
{
id: `${firstResult.title}PlayNext`,
delay: 5000,
duration: 5000,
content: (
<span>
{t('notifications.playingNext', {
@@ -106,7 +106,7 @@ const MostRelevantSearchResultsContainer = (props: Props) => {
[
{
id: `${firstResult.title}AddedToQueue`,
delay: 5000,
duration: 5000,
content: <span>{t('notifications.addedToQueue', { count: 1 })}</span>,
icon: (
<Img
@@ -202,7 +202,7 @@ const MostRelevantSearchResultsContainer = (props: Props) => {
addNewNotifications([
{
id: `${firstResult.name}AddedToQueue`,
delay: 5000,
duration: 5000,
content: (
<span>
{t('notifications.addedToQueue', {
@@ -270,7 +270,7 @@ const MostRelevantSearchResultsContainer = (props: Props) => {
addNewNotifications([
{
id: 'addedToQueue',
delay: 5000,
duration: 5000,
content: (
<span>
{t('notifications.addedToQueue', {
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ const BlacklistedSong = (props: BlacklistedSongProp) => {
addNewNotifications([
{
id: `${title}RestoreSuccess`,
delay: 5000,
duration: 5000,
content: t('notifications.songRestoreSuccess'),
icon: <span className="material-icons-round icon">check</span>
}
Original file line number Diff line number Diff line change
@@ -324,7 +324,7 @@ const AboutSettings = () => {
addNewNotifications([
{
id: 'songHistoryCleared',
delay: 5000,
duration: 5000,
content: <span>{t('settingsPage.songHistoryDeletionSuccess')}</span>
}
]);
Original file line number Diff line number Diff line change
@@ -77,7 +77,7 @@ const SimilarTracksContainer = (props: Props) => {
addNewNotifications([
{
id: `${queueSongIds.length}PlayNext`,
delay: 5000,
duration: 5000,
content: t('notifications.playingNextSongsWithCount', {
count: queueSongIds.length
}),
Original file line number Diff line number Diff line change
@@ -118,7 +118,7 @@ const SongsWithFeaturingArtistsSuggestion = (props: Props) => {
{
content: t('common.featArtistSuggestionResolved'),
iconName: 'done',
delay: 5000,
duration: 5000,
id: 'FeatArtistsSuggestion'
}
]);
@@ -150,7 +150,7 @@ const SongsWithFeaturingArtistsSuggestion = (props: Props) => {
id: 'suggestionIgnored',
iconName: 'do_not_disturb_on',
iconClassName: 'material-icons-round-outlined',
delay: 5000,
duration: 5000,
content: t('notifications.suggestionIgnored')
}
]);
Original file line number Diff line number Diff line change
@@ -120,7 +120,7 @@ const SongLyricsEditorInput = (props: Props) => {
addNewNotifications([
{
id: `fetchUnsyncedLyricsFailed`,
delay: 5000,
duration: 5000,
content: <span>Failed to fetch un-synced lyrics.</span>,
icon: <span className="material-icons-round icon">warning</span>
}
@@ -166,7 +166,7 @@ const SongLyricsEditorInput = (props: Props) => {
addNewNotifications([
{
id: `fetchSyncedLyricsFailed`,
delay: 5000,
duration: 5000,
content: t('songTagsEditingPage.syncedLyricsFetchFailed'),
iconName: 'warning'
}
2 changes: 1 addition & 1 deletion src/renderer/src/components/SongUnplayableErrorPrompt.tsx
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ const SongUnplayableErrorPrompt = (props: Props) => {
addNewNotifications([
{
id: 'unplayableSong',
delay: 10000,
duration: 10000,
content: t('songUnplayableErrorPrompt.title'),
iconName: 'error_outline'
}
Original file line number Diff line number Diff line change
@@ -212,7 +212,7 @@ const CurrentlyPlayingSongInfoContainer = () => {
addNewNotifications([
{
id: `${title}Blacklisted`,
delay: 5000,
duration: 5000,
content: t('notifications.songBlacklisted', { title }),
icon: <span className="material-icons-round">block</span>
}
Original file line number Diff line number Diff line change
@@ -117,7 +117,7 @@ const AddSongsToPlaylistsPrompt = (props: AddSongsToPlaylistProp) => {
return addNewNotifications([
{
id: 'songAddedtoPlaylists',
delay: 5000,
duration: 5000,
iconName: 'playlist_add',
content: t('addSongsToPlaylistsPrompt.songsAddedToPlaylists', {
count: songIds.length,
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ const BlacklistSongConfrimPrompt = (props: { songIds: string[]; title?: string }
return addNewNotifications([
{
id: `${title}Blacklisted`,
delay: 5000,
duration: 5000,
content: t('blacklistSongConfirmPrompt.songsBlacklisted', {
count: songIds.length
}),
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ const DeleteSongFromSystemConfirmPrompt = (props: { songIds: string[] }) => {
addNewNotifications([
{
id: `songRemoved`,
delay: 5000,
duration: 5000,
content: (
<span>
{t(
2 changes: 1 addition & 1 deletion src/renderer/src/components/SongsPage/Song.tsx
Original file line number Diff line number Diff line change
@@ -477,7 +477,7 @@ const Song = forwardRef((props: SongProp, ref: ForwardedRef<HTMLDivElement>) =>
addNewNotifications([
{
id: `${title}Blacklisted`,
delay: 5000,
duration: 5000,
content: t('notifications.songBlacklisted', { title }),
iconName: 'block'
}
2 changes: 1 addition & 1 deletion src/renderer/src/components/SongsPage/SongCard.tsx
Original file line number Diff line number Diff line change
@@ -427,7 +427,7 @@ const SongCard = (props: SongCardProp) => {
addNewNotifications([
{
id: `${title}Blacklisted`,
delay: 5000,
duration: 5000,
content: t('notifications.songBlacklisted', { title }),
iconName: 'block'
}
90 changes: 54 additions & 36 deletions src/renderer/src/other/parseNotificationFromMain.tsx
Original file line number Diff line number Diff line change
@@ -107,10 +107,6 @@ const notificationsFromMainConfig: AppNotificationConfig[] = [
trigger: ['APPDATA_IMPORT_STARTED'],
iconName: 'download'
},
{
trigger: ['APPDATA_EXPORT_STARTED'],
iconName: 'publish'
},
{
trigger: ['MUSIC_FOLDER_DELETED', 'EMPTY_MUSIC_FOLDER_DELETED', 'SONG_DELETED'],
iconName: 'delete',
@@ -132,7 +128,7 @@ const notificationsFromMainConfig: AppNotificationConfig[] = [
},
{
trigger: ['PARSE_FAILED'],
delay: 15000,
duration: 15000,
buttons: [
{
label: i18n.t('settingsPage.resyncLibrary'),
@@ -144,7 +140,7 @@ const notificationsFromMainConfig: AppNotificationConfig[] = [
},
{
trigger: ['PLAYBACK_FROM_UNKNOWN_SOURCE'],
delay: 15000,
duration: 15000,
iconName: 'error',
iconClassName: 'material-icons-round-outlined',
validate({ data }) {
@@ -181,7 +177,7 @@ const notificationsFromMainConfig: AppNotificationConfig[] = [
},
{
trigger: ['SONG_REMOVE_PROCESS_UPDATE', 'AUDIO_PARSING_PROCESS_UPDATE'],
delay: 10000,
duration: 10000,
iconClassName: 'material-icons-round-outlined',
type: 'WITH_PROGRESS_BAR',
validate({ data }) {
@@ -198,9 +194,28 @@ const notificationsFromMainConfig: AppNotificationConfig[] = [
return this;
}
},
{
trigger: ['APPDATA_EXPORT_STARTED'],
iconName: 'publish',
duration: 10000,
iconClassName: 'material-icons-round-outlined',
type: 'WITH_PROGRESS_BAR',
validate({ data }) {
if (data) return 'total' in data && 'value' in data;
return false;
},
update({ data }) {
this.progressBarData = {
total: (data?.total as number) || 0,
value: (data?.value as number) || 0
};

return this;
}
},
{
trigger: ['SONG_PALETTE_GENERATING_PROCESS_UPDATE', 'GENRE_PALETTE_GENERATING_PROCESS_UPDATE'],
delay: 10000,
duration: 10000,
iconName: 'magic_button',
iconClassName: 'material-icons-round-outlined',
type: 'WITH_PROGRESS_BAR',
@@ -219,7 +234,7 @@ const notificationsFromMainConfig: AppNotificationConfig[] = [
this.progressBarData.total !== 0 &&
this.progressBarData.total === this.progressBarData.value
)
this.delay = 5000;
this.duration = 5000;
return this;
}
}
@@ -247,38 +262,41 @@ const parseNotificationFromMain = (

for (const config of notificationsFromMainConfig) {
const { trigger, validate = () => true, update } = config;
const validateFunc = validate.bind(config);

if (trigger.includes(messageCode) && validateFunc(obj)) {
let configData = config;
if (update) configData = update.bind(configData, obj)();
if (trigger.includes(messageCode)) {
const validateFunc = validate.bind(config);

if (validateFunc(obj)) {
let configData = config;
if (update) configData = update.bind(configData, obj)();

const {
id,
delay,
buttons,
progressBarData,
type,
content: notificationContent,
order,
icon,
iconName,
iconClassName
} = configData;
const {
id,
duration,
buttons,
progressBarData,
type,
content: notificationContent,
order,
icon,
iconName,
iconClassName
} = configData;

if (id) notificationData.id = id;
if (delay) notificationData.delay = delay;
if (buttons) notificationData.buttons = buttons;
if (type) notificationData.type = type;
if (order) notificationData.order = order;
if (notificationContent) notificationData.content = notificationContent;
if (progressBarData) notificationData.progressBarData = progressBarData;
if (id) notificationData.id = id;
if (duration) notificationData.duration = duration;
if (buttons) notificationData.buttons = buttons;
if (type) notificationData.type = type;
if (order) notificationData.order = order;
if (notificationContent) notificationData.content = notificationContent;
if (progressBarData) notificationData.progressBarData = progressBarData;

if (icon) notificationData.icon = icon;
if (iconName) notificationData.iconName = iconName;
if (iconClassName) notificationData.iconClassName = iconClassName;
if (icon) notificationData.icon = icon;
if (iconName) notificationData.iconName = iconName;
if (iconClassName) notificationData.iconClassName = iconClassName;

break;
break;
}
}
}
}