|
1 | | -import { env, ExtensionContext, Uri, window } from 'vscode'; |
| 1 | +import { |
| 2 | + commands, |
| 3 | + env, |
| 4 | + ExtensionContext, |
| 5 | + extensions, |
| 6 | + Uri, |
| 7 | + window, |
| 8 | +} from 'vscode'; |
2 | 9 |
|
3 | | -const FIRST_SHOWN_KEY = 'r5n.migrated.firstShownAt'; |
| 10 | +const LAST_SHOWN_KEY = 'r5n.migrated.lastShownAt'; |
4 | 11 | const DISMISSED_KEY = 'r5n.migrated.dismissed'; |
5 | 12 | const NEW_EXTENSION_ID = 'r5n.es-js-snippets'; |
| 13 | +const OLD_EXTENSION_ID = 'dsznajder.es7-react-js-snippets'; |
6 | 14 | const REMINDER_AFTER_MS = 7 * 24 * 60 * 60 * 1000; |
| 15 | +const MIGRATE_ACTION = 'Migrate to new extension'; |
| 16 | +const DISMISS_ACTION = "Don't show again"; |
| 17 | +const RELOAD_ACTION = 'Reload Window'; |
7 | 18 |
|
8 | 19 | const INITIAL_MESSAGE = |
9 | 20 | 'ES7+ React/Redux/React-Native snippets has moved. Install the new version (r5n.es-js-snippets) for React 17–19 support and ongoing updates.'; |
10 | 21 |
|
11 | | -const FINAL_MESSAGE = |
12 | | - 'Final reminder: this extension has moved to r5n.es-js-snippets and is no longer maintained here.'; |
| 22 | +const REMINDER_MESSAGE = |
| 23 | + 'Reminder: this extension has moved to r5n.es-js-snippets and is no longer maintained here.'; |
| 24 | + |
| 25 | +const FINISH_MESSAGE = |
| 26 | + 'The new r5n.es-js-snippets extension is installed. Finish migration by uninstalling this deprecated extension.'; |
13 | 27 |
|
14 | 28 | export async function showMigrationNotice( |
15 | 29 | context: ExtensionContext, |
16 | 30 | ): Promise<void> { |
17 | 31 | if (context.globalState.get(DISMISSED_KEY) === true) return; |
18 | 32 |
|
19 | 33 | const now = Date.now(); |
20 | | - const firstShownAt = context.globalState.get<number>(FIRST_SHOWN_KEY); |
| 34 | + const lastShownAt = context.globalState.get<number>(LAST_SHOWN_KEY); |
21 | 35 |
|
22 | | - if (firstShownAt === undefined) { |
23 | | - await context.globalState.update(FIRST_SHOWN_KEY, now); |
24 | | - await showToast(context, INITIAL_MESSAGE, false); |
| 36 | + if (lastShownAt !== undefined && now - lastShownAt < REMINDER_AFTER_MS) { |
25 | 37 | return; |
26 | 38 | } |
27 | 39 |
|
28 | | - if (now - firstShownAt >= REMINDER_AFTER_MS) { |
29 | | - await showToast(context, FINAL_MESSAGE, true); |
30 | | - await context.globalState.update(DISMISSED_KEY, true); |
31 | | - } |
| 40 | + await context.globalState.update(LAST_SHOWN_KEY, now); |
| 41 | + await showToast( |
| 42 | + context, |
| 43 | + extensions.getExtension(NEW_EXTENSION_ID) !== undefined |
| 44 | + ? FINISH_MESSAGE |
| 45 | + : lastShownAt === undefined |
| 46 | + ? INITIAL_MESSAGE |
| 47 | + : REMINDER_MESSAGE, |
| 48 | + ); |
32 | 49 | } |
33 | 50 |
|
34 | 51 | async function showToast( |
35 | 52 | context: ExtensionContext, |
36 | 53 | message: string, |
37 | | - finalNudge: boolean, |
38 | 54 | ): Promise<void> { |
39 | 55 | const action = await window.showInformationMessage( |
40 | 56 | message, |
41 | | - 'Install new version', |
42 | | - "Don't show again", |
| 57 | + MIGRATE_ACTION, |
| 58 | + DISMISS_ACTION, |
43 | 59 | ); |
44 | 60 |
|
45 | | - if (action === 'Install new version') { |
46 | | - await env.openExternal(Uri.parse(`vscode:extension/${NEW_EXTENSION_ID}`)); |
47 | | - await context.globalState.update(DISMISSED_KEY, true); |
| 61 | + if (action === MIGRATE_ACTION) { |
| 62 | + await migrateToNewExtension(); |
48 | 63 | return; |
49 | 64 | } |
50 | 65 |
|
51 | | - if (action === "Don't show again" || finalNudge) { |
| 66 | + if (action === DISMISS_ACTION) { |
52 | 67 | await context.globalState.update(DISMISSED_KEY, true); |
53 | 68 | } |
54 | 69 | } |
| 70 | + |
| 71 | +async function migrateToNewExtension(): Promise<void> { |
| 72 | + try { |
| 73 | + if (extensions.getExtension(NEW_EXTENSION_ID) === undefined) { |
| 74 | + await commands.executeCommand( |
| 75 | + 'workbench.extensions.installExtension', |
| 76 | + NEW_EXTENSION_ID, |
| 77 | + { enable: true }, |
| 78 | + ); |
| 79 | + } |
| 80 | + |
| 81 | + await commands.executeCommand( |
| 82 | + 'workbench.extensions.uninstallExtension', |
| 83 | + OLD_EXTENSION_ID, |
| 84 | + ); |
| 85 | + |
| 86 | + const action = await window.showInformationMessage( |
| 87 | + 'Migration started. Reload VS Code to finish removing this deprecated extension.', |
| 88 | + RELOAD_ACTION, |
| 89 | + ); |
| 90 | + |
| 91 | + if (action === RELOAD_ACTION) { |
| 92 | + await commands.executeCommand('workbench.action.reloadWindow'); |
| 93 | + } |
| 94 | + } catch { |
| 95 | + await env.openExternal(Uri.parse(`vscode:extension/${NEW_EXTENSION_ID}`)); |
| 96 | + await window.showWarningMessage( |
| 97 | + 'Automatic migration failed. Install r5n.es-js-snippets from the opened extension page, then uninstall this deprecated extension.', |
| 98 | + ); |
| 99 | + } |
| 100 | +} |
0 commit comments