[READ-ONLY] Mirror of https://github.com/probablykasper/ferrum. Music library app for Mac, Linux and Windows ferrum.kasper.space
electron linux macos music music-library music-player napi windows
0

Configure Feed

Select the types of activity you want to include in your feed.

Add auto update setting

Kasper (Oct 8, 2024, 3:28 AM +0200) 4abe6536 7fb91d3b

+98 -29
+2
ferrum-addon/addon.d.ts
··· 186 186 shownPlaylistFolders: Array<string> 187 187 /** Empty is treated as default */ 188 188 columns: Array<string> 189 + /** Auto update checking */ 190 + noAutoUpdate: boolean 189 191 skipUpdatingToVersion?: string 190 192 } 191 193 export declare function load_view_options(): ViewOptions
+4
src-native/view_options.rs
··· 15 15 pub shown_playlist_folders: Vec<String>, 16 16 /// Empty is treated as default 17 17 pub columns: Vec<String>, 18 + /// Auto update checking 19 + #[serde(default)] 20 + pub no_auto_update: bool, 18 21 pub skip_updating_to_version: Option<String>, 19 22 } 20 23 impl ViewOptions { ··· 24 27 Err(_) => ViewOptions { 25 28 shown_playlist_folders: Vec::new(), 26 29 columns: Vec::new(), 30 + no_auto_update: false, 27 31 skip_updating_to_version: None, 28 32 }, 29 33 }
+14 -1
src/App.svelte
··· 22 22 import { navigate_back, navigate_forward } from './lib/router' 23 23 import './lib/router' 24 24 import CheckForUpdates from './components/CheckForUpdates.svelte' 25 + import Settings from './components/Settings.svelte' 25 26 26 27 ipc_renderer.invoke('app_loaded').catch(() => { 27 28 ipc_renderer.invoke('showMessageBox', false, { ··· 110 111 } 111 112 } 112 113 114 + let show_settings = false 115 + onDestroy( 116 + ipc_listen('show_settings', () => { 117 + if ($modal_count === 0) { 118 + show_settings = true 119 + } 120 + }), 121 + ) 122 + 113 123 let show_itunes_import = false 114 124 onDestroy( 115 125 ipc_listen('itunesImport', () => { ··· 217 227 {/if} 218 228 </main> 219 229 230 + <QuickNav /> 220 231 {#if $current_list} 221 232 <TrackInfo /> 222 233 {/if} ··· 226 237 {#if show_itunes_import} 227 238 <ItunesImport cancel={() => (show_itunes_import = false)} /> 228 239 {/if} 229 - <QuickNav /> 240 + {#if show_settings} 241 + <Settings on_close={() => (show_settings = false)} /> 242 + {/if} 230 243 <CheckForUpdates /> 231 244 232 245 <DragGhost />
+4 -3
src/components/CheckForUpdates.svelte
··· 8 8 9 9 check() 10 10 async function check() { 11 - if (is_dev || !window.navigator.onLine) { 11 + if (is_dev || !window.navigator.onLine || view_options.noAutoUpdate) { 12 12 return 13 13 } 14 14 const result = await ipc_renderer.invoke('check_for_updates') ··· 38 38 form={() => ipc_renderer.invoke('open_url', channel.url)} 39 39 title="A new version of Ferrum is available!" 40 40 > 41 - <!-- svelte-ignore a11y-no-noninteractive-tabindex --> 42 41 <div class="max-w-xl text-sm"> 43 42 <p class="pb-3"> 44 43 Ferrum {latest_update.channel.version} is available. You are currently on {latest_update.app_version} ··· 58 57 > 59 58 <div class="grow"></div> 60 59 <Button secondary autofocus on:click={() => (latest_update = null)}>Later</Button> 61 - <Button on:click={() => ipc_renderer.invoke('open_url', channel.url)}>Update</Button> 60 + <Button type="submit" on:click={() => ipc_renderer.invoke('open_url', channel.url)} 61 + >Update</Button 62 + > 62 63 </svelte:fragment> 63 64 </Modal> 64 65 {/if}
+32
src/components/Settings.svelte
··· 1 + <script lang="ts"> 2 + import Modal from './Modal.svelte' 3 + import Button from './Button.svelte' 4 + import { save_view_options, view_options } from '@/lib/data' 5 + 6 + export let on_close: () => void 7 + 8 + let auto_update = !view_options.noAutoUpdate 9 + 10 + function save() { 11 + view_options.noAutoUpdate = !auto_update 12 + save_view_options(view_options) 13 + on_close() 14 + } 15 + </script> 16 + 17 + <Modal on_cancel={on_close} cancel_on_escape form={save} title="Settings"> 18 + <div class="w-96 text-sm"> 19 + <label class="flex items-center gap-2"> 20 + <input 21 + type="checkbox" 22 + class="size-3.5 border-gray-300 bg-gray-100 text-blue-600 outline-offset-2 outline-blue-500 outline-solid focus-visible:outline" 23 + bind:checked={auto_update} 24 + /> 25 + Automatically check for updates on startup 26 + </label> 27 + </div> 28 + <svelte:fragment slot="buttons"> 29 + <Button secondary on:click={on_close}>Cancel</Button> 30 + <Button type="submit" on:click={save}>Save</Button> 31 + </svelte:fragment> 32 + </Modal>
+41 -24
src/electron/menubar.ts
··· 21 21 submenu: [ 22 22 { role: 'about' }, 23 23 { type: 'separator' }, 24 + { 25 + label: 'Settings...', 26 + accelerator: 'CmdOrCtrl+,', 27 + click() { 28 + web_contents.send('show_settings') 29 + }, 30 + }, 31 + { type: 'separator' }, 24 32 { role: 'services' }, 25 33 { type: 'separator' }, 26 34 { role: 'hide' }, ··· 37 45 { 38 46 label: 'New Playlist', 39 47 accelerator: 'CmdOrCtrl+N', 40 - click: () => { 48 + click() { 41 49 web_contents.send('newPlaylist', 'root', false) 42 50 }, 43 51 }, 44 52 { 45 53 label: 'New Playlist Folder', 46 - click: () => { 54 + click() { 47 55 web_contents.send('newPlaylist', 'root', true) 48 56 }, 49 57 }, ··· 51 59 { 52 60 label: 'Import...', 53 61 accelerator: 'CmdOrCtrl+O', 54 - click: () => { 62 + click() { 55 63 web_contents.send('import') 56 64 }, 57 65 }, 58 66 { type: 'separator' }, 59 67 { 60 68 label: 'Import iTunes Library...', 61 - click: () => { 69 + click() { 62 70 web_contents.send('itunesImport') 63 71 }, 64 72 }, 65 73 { type: 'separator' }, 74 + { 75 + label: 'Settings...', 76 + accelerator: 'CmdOrCtrl+,', 77 + click() { 78 + web_contents.send('show_settings') 79 + }, 80 + visible: !is.mac, 81 + }, 82 + { type: 'separator', visible: !is.mac }, 66 83 is.mac ? { role: 'close' } : { role: 'quit' }, 67 84 ], 68 85 }, ··· 87 104 menu.push({ 88 105 label: 'Filter', 89 106 accelerator: 'CmdOrCtrl+F', 90 - click: () => { 107 + click() { 91 108 web_contents.send('filter') 92 109 }, 93 110 }) ··· 100 117 { 101 118 label: 'Play Next', 102 119 accelerator: '', 103 - click: () => { 120 + click() { 104 121 web_contents.send('selected_tracks_action', 'Play Next') 105 122 }, 106 123 }, 107 124 { 108 125 label: 'Add to Queue', 109 126 accelerator: '', 110 - click: () => { 127 + click() { 111 128 web_contents.send('selected_tracks_action', 'Add to Queue') 112 129 }, 113 130 }, ··· 115 132 { 116 133 label: 'Get Info', 117 134 accelerator: 'CmdOrCtrl+I', 118 - click: () => { 135 + click() { 119 136 web_contents.send('selected_tracks_action', 'Get Info') 120 137 }, 121 138 }, ··· 127 144 else return 'Reveal in File Manager' 128 145 })(), 129 146 accelerator: 'Shift+CmdOrCtrl+R', 130 - click: () => { 147 + click() { 131 148 web_contents.send('selected_tracks_action', 'reveal_track_file') 132 149 }, 133 150 }, ··· 135 152 { 136 153 label: 'Remove from Playlist', 137 154 accelerator: '', 138 - click: () => { 155 + click() { 139 156 web_contents.send('selected_tracks_action', 'Remove from Playlist') 140 157 }, 141 158 }, 142 159 { 143 160 label: 'Delete from Library', 144 161 accelerator: 'CmdOrCtrl+Backspace', 145 - click: () => { 162 + click() { 146 163 web_contents.send('selected_tracks_action', 'Delete from Library') 147 164 }, 148 165 }, ··· 156 173 id: 'Show Queue', 157 174 type: 'checkbox', 158 175 accelerator: 'CmdOrCtrl+U', 159 - click: () => { 176 + click() { 160 177 web_contents.send('Show Queue') 161 178 }, 162 179 }, ··· 164 181 label: 'Toggle Quick Nav', 165 182 type: 'checkbox', 166 183 accelerator: 'CmdOrCtrl+K', 167 - click: () => { 184 + click() { 168 185 web_contents.send('ToggleQuickNav') 169 186 }, 170 187 }, ··· 194 211 { 195 212 label: 'Pause', 196 213 // no accelerator because it's unreliable 197 - click: () => { 214 + click() { 198 215 web_contents.send('playPause') 199 216 }, 200 217 }, 201 218 { 202 219 label: 'Next', 203 220 accelerator: 'CmdOrCtrl+Right', 204 - click: () => { 221 + click() { 205 222 web_contents.send('Next') 206 223 }, 207 224 }, 208 225 { 209 226 label: 'Previous', 210 227 accelerator: 'CmdOrCtrl+Left', 211 - click: () => { 228 + click() { 212 229 web_contents.send('Previous') 213 230 }, 214 231 }, ··· 218 235 id: 'Shuffle', 219 236 type: 'checkbox', 220 237 accelerator: 'CmdOrCtrl+S', 221 - click: () => { 238 + click() { 222 239 web_contents.send('Shuffle') 223 240 }, 224 241 }, ··· 227 244 id: 'Repeat', 228 245 type: 'checkbox', 229 246 accelerator: 'CmdOrCtrl+R', 230 - click: () => { 247 + click() { 231 248 web_contents.send('Repeat') 232 249 }, 233 250 }, ··· 236 253 id: 'Volume Up', 237 254 label: 'Volume Up', 238 255 accelerator: 'CmdOrCtrl+Up', 239 - click: () => { 256 + click() { 240 257 web_contents.send('volumeUp') 241 258 }, 242 259 }, ··· 244 261 id: 'Volume Down', 245 262 label: 'Volume Down', 246 263 accelerator: 'CmdOrCtrl+Down', 247 - click: () => { 264 + click() { 248 265 web_contents.send('volumeDown') 249 266 }, 250 267 }, ··· 257 274 id: 'Back', 258 275 label: 'Back', 259 276 accelerator: 'CmdOrCtrl+[', 260 - click: () => { 277 + click() { 261 278 web_contents.send('Back') 262 279 }, 263 280 }, ··· 265 282 id: 'Forward', 266 283 label: 'Forward', 267 284 accelerator: 'CmdOrCtrl+]', 268 - click: () => { 285 + click() { 269 286 web_contents.send('Forward') 270 287 }, 271 288 }, ··· 274 291 id: 'Select Next List', 275 292 label: 'Select Next List', 276 293 accelerator: 'Ctrl+Tab', 277 - click: () => { 294 + click() { 278 295 web_contents.send('Select Next List') 279 296 }, 280 297 }, ··· 282 299 id: 'Select Previous List', 283 300 label: 'Select Previous List', 284 301 accelerator: 'Ctrl+Shift+Tab', 285 - click: () => { 302 + click() { 286 303 web_contents.send('Select Previous List') 287 304 }, 288 305 },
+1
src/electron/typed_ipc.ts
··· 103 103 gonnaQuit: () => void 104 104 105 105 newPlaylist: (id: string, isFolder: boolean) => void 106 + show_settings: () => void 106 107 itunesImport: () => void 107 108 import: () => void 108 109 filter: () => void
-1
src/electron/update.ts
··· 1 1 import { app, dialog } from 'electron' 2 2 import package_json from '../../package.json' 3 - import is from './is' 4 3 5 4 export type UpdateJson = { 6 5 [channel: string]: {