1- import axios from 'axios' ;
2- import luxon from 'luxon' ;
3- import * as settings from 'src/utils/settings/index.js' ;
41import style from 'src/utils/style.js' ;
52import wrap from 'src/utils/2.pokemon.js' ;
63import debugToast from 'src/utils/debugToast' ;
7- import { toast as BasicToast } from 'src/utils/2.toasts.js' ;
8- import sleep from 'src/utils/sleep.js' ;
9- import * as menu from 'src/utils/menu.js' ;
4+ import { toast as Toast } from 'src/utils/2.toasts.js' ;
105import semver from 'src/utils/version.js' ;
116import { buttonCSS , scriptVersion } from 'src/utils/1.variables.js' ;
127import css from 'src/utils/css.js' ;
13- import { captureError } from 'src/utils/sentry.js' ;
8+ import createParser from 'src/utils/parser' ;
9+ import eventManager from 'src/utils/eventManager' ;
10+ import {
11+ register ,
12+ unregister ,
13+ validate ,
14+ } from 'src/hooks/updates' ;
15+ import plugin from 'src/utils/underscript' ;
1416
1517// Check for script updates
1618wrap ( ( ) => {
17- const disabled = settings . register ( {
18- name : 'Disable Auto Updates' ,
19- key : 'underscript.disable.updates' ,
20- } ) ;
21-
2219 style . add ( css `
2320 # AlertToast h2 ,
2421 # AlertToast h3 {
@@ -30,160 +27,61 @@ wrap(() => {
3027 font-size : 17px ;
3128 }
3229 ` ) ;
33- const baseURL = 'https://unpkg.com/' ;
34- const MINUTE = 60 * 1000 ;
35- const HOUR = 60 * MINUTE ;
36- const CHECKING = 'underscript.update.checking' ;
37- const LAST = 'underscript.update.last' ;
38- const DEBUG = 'underscript.debug.update' ;
39- const LATEST = 'underscript.update.latest' ;
40- const base = axios . create ( { baseURL } ) ;
41- const latest = { // TODO: can I get away with storing this in sessionStorage?
42- set ( { version, unpkg } ) {
43- if ( ! version || ! unpkg ) return ;
44- localStorage . setItem ( LATEST , JSON . stringify ( {
45- version,
46- unpkg,
47- time : Date . now ( ) ,
48- } ) ) ;
49- } ,
50- del ( ) {
51- localStorage . removeItem ( LATEST ) ;
52- } ,
53- chk ( ) {
54- const stored = JSON . parse ( localStorage . getItem ( LATEST ) ) ;
55- if ( stored ) {
56- return compareAndToast ( stored ) ;
57- }
58- return false ;
59- } ,
60- } ;
61- let toast ;
30+ const checker = createParser ( { updateURL : 'UCProjects/UnderScript' } ) ;
31+ const DEBUG = 'underscript.update.debug' ;
6232 let updateToast ;
63- let autoTimeout ;
64- function check ( ) {
65- if ( sessionStorage . getItem ( CHECKING ) ) return Promise . resolve ( ) ;
66- sessionStorage . setItem ( CHECKING , true ) ;
67- return base . get ( `underscript@latest/package.json` ) . then ( ( response ) => {
68- sessionStorage . removeItem ( CHECKING ) ;
69- localStorage . setItem ( LAST , Date . now ( ) ) ;
70- return response ;
71- } ) . catch ( ( error ) => {
72- captureError ( error ) ;
73- sessionStorage . removeItem ( CHECKING ) ;
74- debugToast ( error ) ;
75- if ( toast ) {
76- toast . setText ( 'Failed to connect to server.' ) ;
77- }
78- } ) ;
79- }
80- function noUpdateFound ( ) {
81- const ref = toast ;
82- if ( ref && ref . exists ( ) ) {
83- ref . setText ( 'No updates available.' ) ;
84- sleep ( 3000 ) . then ( ref . close ) ;
85- }
86- }
8733 function isNewer ( data ) {
8834 const version = scriptVersion ;
8935 if ( version === 'L' && ! localStorage . getItem ( DEBUG ) ) return false ;
90- if ( data . time && data . time < GM_info . script . lastModified ) return false ; // Check if stored version is newer than script date
9136 if ( version . includes ( '-' ) ) return semver ( data . version , version ) ; // Allow test scripts to update to release
9237 return data . version !== version ; // Always assume that the marked version is better
9338 }
9439 function compareAndToast ( data ) {
95- if ( ! isNewer ( data ) ) {
96- latest . del ( ) ;
97- return false ;
98- }
99- latest . set ( data ) ;
100- if ( updateToast ) updateToast . close ( 'stale' ) ;
101- const path = `underscript@${ data . version } /${ data . unpkg } ` ;
102- updateToast = BasicToast ( {
103- title : '[UnderScript] Update Available!' ,
104- text : `Version ${ data . version } .` ,
105- className : 'dismissable' ,
106- buttons : [ {
107- text : 'Update (github)' ,
108- className : 'dismiss' ,
109- css : buttonCSS ,
110- } , {
111- text : 'Update (unpkg)' ,
112- className : 'dismiss' ,
113- css : buttonCSS ,
114- onclick ( e ) {
115- location . href = `${ baseURL } /${ path } ` ;
116- updateToast . close ( 'update' ) ;
117- } ,
118- } , {
119- text : 'Update (jsdelivr)' ,
120- className : 'dismiss' ,
121- css : buttonCSS ,
122- onclick : ( e ) => {
123- location . href = `https://cdn.jsdelivr.net/npm/${ path } ` ;
124- updateToast . close ( 'update' ) ;
125- } ,
126- } ] ,
127- onClose ( reason ) {
128- if ( reason !== 'dismissed' ) return ;
129- location . href = `https://github.com/UCProjects/UnderScript/releases/download/${ data . version } /undercards.user.js` ;
130- } ,
40+ if ( ! data || ! isNewer ( data ) ) return false ;
41+ eventManager . once ( ':update:finished :update:force' , ( ) => {
42+ updateToast ?. close ( 'stale' ) ;
43+ updateToast = Toast ( {
44+ title : '[UnderScript] Update Available!' ,
45+ text : `Version ${ data . version } .` ,
46+ className : 'dismissable' ,
47+ buttons : [ {
48+ text : 'Update' ,
49+ className : 'dismiss' ,
50+ css : buttonCSS ,
51+ onclick ( ) {
52+ location . href = data . url || `https://github.com/UCProjects/UnderScript/releases/download/${ data . version } /undercards.user.js` ;
53+ } ,
54+ } ] ,
55+ } ) ;
13156 } ) ;
13257 return true ;
13358 }
134- function autoCheck ( ) {
135- // It passed, don't need to check anymore
136- if ( latest . chk ( ) ) return ;
137- check ( ) . then ( ( { data } = { } ) => {
138- if ( data ) {
139- compareAndToast ( data ) ;
59+ eventManager . on ( ':update' , async ( auto ) => {
60+ if ( ! auto ) {
61+ unregister ( plugin ) ;
62+ }
63+ try {
64+ const data = await checker . getUpdateData ( ) ;
65+ const update = {
66+ url : await checker . getDownload ( data ) ,
67+ version : await checker . getVersion ( data ) ,
68+ time : data . assets . find ( ( { name } ) => name . endsWith ( '.user.js' ) ) . updated_at ,
69+ } ;
70+ if ( compareAndToast ( update ) ) {
71+ register ( {
72+ ...update ,
73+ plugin,
74+ announce : false ,
75+ } ) ;
14076 }
141- // One hour from now or one minute from now (if an error occurred)
142- autoTimeout = setTimeout ( autoCheck , data ? HOUR : MINUTE ) ;
143- } ) ;
144- }
145- // Frequency - when should it check for updates
146- // Menu button - Manual update check
147- menu . addButton ( {
148- text : 'Check for updates' ,
149- action ( ) {
150- if ( updateToast && updateToast . exists ( ) ) return ;
151- if ( toast ) toast . close ( ) ;
152- toast = BasicToast ( {
153- title : 'UnderScript updater' ,
154- text : 'Checking for updates. Please wait.' ,
155- } ) ;
156- latest . del ( ) ; // Clear latest cache on manual check
157- check ( ) . then ( ( { data } = { } ) => {
158- setupAuto ( ) ; // Setup a new auto check (wait another hour)
159- if ( ! data ) return ;
160- if ( ! isNewer ( data ) ) {
161- noUpdateFound ( ) ;
162- } else {
163- toast . close ( ) ; // I need a way to change the 'onclose'
164- compareAndToast ( data ) ;
165- }
166- } ) ;
167- } ,
168- note ( ) {
169- const last = parseInt ( localStorage . getItem ( LAST ) , 10 ) ;
170- return `Last Checked: ${ last ? luxon . DateTime . fromMillis ( last ) . toLocaleString ( luxon . DateTime . DATETIME_FULL ) : 'never' } ` ;
171- } ,
172- } ) ;
173-
174- function setupAuto ( ) {
175- if ( disabled . value ( ) ) return ;
176- if ( autoTimeout ) clearTimeout ( autoTimeout ) ;
177- const last = parseInt ( localStorage . getItem ( LAST ) , 10 ) ;
178- const now = Date . now ( ) ;
179- const timeout = last - now + HOUR ;
180- if ( ! last || timeout <= 0 ) {
181- autoCheck ( ) ;
182- } else {
183- autoTimeout = setTimeout ( autoCheck , timeout ) ;
77+ } catch ( error ) {
78+ debugToast ( error ) ;
18479 }
185- }
80+ } ) ;
18681
187- sessionStorage . removeItem ( CHECKING ) ;
188- if ( ! latest . chk ( ) ) setupAuto ( ) ;
82+ // Toast if update pending
83+ eventManager . on ( 'underscript:ready' , ( ) => {
84+ compareAndToast ( validate ( plugin ) ) ;
85+ eventManager . emit ( ':update:force' ) ;
86+ } ) ;
18987} ) ;
0 commit comments