11/* eslint-disable node/prefer-global/process */
22import { repository , version } from '../../../package.json'
33import { send } from '../ipc'
4+ import { store } from '../store'
45
56interface GitHubRelease {
67 tag_name : string
78}
89
910const INTERVAL = 1000 * 60 * 60 * 3 // 3 часа
1011const isDev = process . env . NODE_ENV === 'development'
12+ const currentVersionParts = parseVersion ( version ) !
13+ const currentMajorVersion = currentVersionParts [ 0 ]
1114
12- export async function fethUpdates ( ) {
15+ function parseVersion ( rawVersion : string ) : [ number , number , number ] | null {
16+ const normalizedVersion = rawVersion . trim ( ) . replace ( / ^ v / , '' )
17+ const match = normalizedVersion . match ( / ^ ( \d + ) \. ( \d + ) \. ( \d + ) $ / )
18+
19+ if ( ! match ) {
20+ return null
21+ }
22+
23+ return [
24+ Number . parseInt ( match [ 1 ] , 10 ) ,
25+ Number . parseInt ( match [ 2 ] , 10 ) ,
26+ Number . parseInt ( match [ 3 ] , 10 ) ,
27+ ]
28+ }
29+
30+ function compareVersions (
31+ left : [ number , number , number ] ,
32+ right : [ number , number , number ] ,
33+ ) : 1 | - 1 | 0 {
34+ for ( let i = 0 ; i < 3 ; i += 1 ) {
35+ if ( left [ i ] === right [ i ] ) {
36+ continue
37+ }
38+
39+ return left [ i ] > right [ i ] ? 1 : - 1
40+ }
41+
42+ return 0
43+ }
44+
45+ function getLatestReleaseVersion ( releases : GitHubRelease [ ] ) {
46+ let latestParsedVersion : [ number , number , number ] | null = null
47+
48+ for ( const release of releases ) {
49+ const parsedVersion = parseVersion ( release . tag_name )
50+ if ( ! parsedVersion || parsedVersion [ 0 ] !== currentMajorVersion ) {
51+ continue
52+ }
53+
54+ if (
55+ ! latestParsedVersion
56+ || compareVersions ( parsedVersion , latestParsedVersion ) > 0
57+ ) {
58+ latestParsedVersion = parsedVersion
59+ }
60+ }
61+
62+ return latestParsedVersion ?. join ( '.' )
63+ }
64+
65+ function isNewerVersion ( versionToCompare : string ) {
66+ const parsedVersion = parseVersion ( versionToCompare )
67+ if ( ! parsedVersion ) {
68+ return false
69+ }
70+
71+ return compareVersions ( parsedVersion , currentVersionParts ) > 0
72+ }
73+
74+ export async function fetchUpdates ( ) {
1375 if ( isDev ) {
1476 return
1577 }
@@ -18,36 +80,44 @@ export async function fethUpdates() {
1880 const url = `${ repository . replace ( 'github.com' , 'api.github.com/repos' ) } /releases`
1981
2082 const response = await fetch ( url )
21- const data = ( await response . json ( ) ) as GitHubRelease [ ]
22-
23- if ( ! data ) {
83+ if ( ! response . ok ) {
2484 return
2585 }
2686
27- const releases = data . filter ( ( release ) => {
28- const tagName = release . tag_name . replace ( 'v' , '' )
29- return tagName . startsWith ( '4.' )
30- } )
31-
32- if ( releases . length > 0 ) {
33- const latestRelease = releases [ 0 ]
34- const latestVersion = latestRelease . tag_name . replace ( 'v' , '' )
87+ const data = ( await response . json ( ) ) as GitHubRelease [ ]
88+ if ( ! Array . isArray ( data ) || data . length === 0 ) {
89+ return
90+ }
3591
36- if ( latestVersion !== version ) {
37- send ( 'system:update-available' )
38- return latestVersion as string
39- }
92+ const latestVersion = getLatestReleaseVersion ( data )
93+ if ( latestVersion && isNewerVersion ( latestVersion ) ) {
94+ return latestVersion
4095 }
4196 }
4297 catch ( err ) {
4398 console . error ( 'Error checking for updates:' , err )
4499 }
45100}
46101
102+ async function notifyAboutUpdate ( ) {
103+ const latestVersion = await fetchUpdates ( )
104+ if ( ! latestVersion ) {
105+ return
106+ }
107+
108+ const lastNotifiedVersion = store . app . get ( 'lastNotifiedUpdateVersion' )
109+ if ( lastNotifiedVersion === latestVersion ) {
110+ return
111+ }
112+
113+ send ( 'system:update-available' )
114+ store . app . set ( 'lastNotifiedUpdateVersion' , latestVersion )
115+ }
116+
47117export function checkForUpdates ( ) {
48- fethUpdates ( )
118+ void notifyAboutUpdate ( )
49119
50120 setInterval ( ( ) => {
51- fethUpdates ( )
121+ void notifyAboutUpdate ( )
52122 } , INTERVAL )
53123}
0 commit comments