-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: integrate auto_updater for macOS (#7328)
* feat: integrate auto_updater in macOS * chore: update translations * chore: bump auto_updater version * feat: exclude linux platform in auto update task * chore: disable auto updater * fix: integration tests * fix: integration tests
- Loading branch information
Showing
30 changed files
with
949 additions
and
206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
-----BEGIN PUBLIC KEY----- | ||
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 | ||
p6Dfx6Mqf0+pSpyZcf+qW1vlk3q92g== | ||
-----END PUBLIC KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
188 changes: 188 additions & 0 deletions
188
frontend/appflowy_flutter/lib/startup/tasks/auto_update_task.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
import 'package:appflowy/generated/locale_keys.g.dart'; | ||
import 'package:appflowy/startup/tasks/app_widget.dart'; | ||
import 'package:appflowy/startup/tasks/device_info_task.dart'; | ||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; | ||
import 'package:appflowy_backend/log.dart'; | ||
import 'package:auto_updater/auto_updater.dart'; | ||
import 'package:collection/collection.dart'; | ||
import 'package:easy_localization/easy_localization.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:universal_platform/universal_platform.dart'; | ||
|
||
import '../startup.dart'; | ||
|
||
class AutoUpdateTask extends LaunchTask { | ||
AutoUpdateTask(); | ||
|
||
// static const _feedUrl = | ||
// 'https://github.com/LucasXu0/AppFlowy/releases/latest/download/appcast-{os}-{arch}.xml'; | ||
final _listener = _AppFlowyAutoUpdaterListener(); | ||
|
||
@override | ||
Future<void> initialize(LaunchContext context) async { | ||
// Enable auto update when the integration of Windows and Linux is completed. | ||
return; | ||
// // the auto updater is not supported on mobile and linux | ||
// if (UniversalPlatform.isMobile || UniversalPlatform.isLinux) { | ||
// return; | ||
// } | ||
|
||
// Log.info( | ||
// '[AutoUpdate] current version: ${ApplicationInfo.applicationVersion}, current cpu architecture: ${ApplicationInfo.architecture}', | ||
// ); | ||
|
||
// autoUpdater.addListener(_listener); | ||
|
||
// // Since the appcast.xml is not supported the arch, we separate the feed url by os and arch. | ||
// final feedUrl = _feedUrl | ||
// .replaceAll('{os}', ApplicationInfo.os) | ||
// .replaceAll('{arch}', ApplicationInfo.architecture); | ||
// Log.info('[AutoUpdate] feed url: $feedUrl'); | ||
|
||
// await autoUpdater.setFeedURL(feedUrl); | ||
// await autoUpdater.checkForUpdateInformation(); | ||
|
||
// ApplicationInfo.isCriticalUpdateNotifier.addListener( | ||
// _showCriticalUpdateDialog, | ||
// ); | ||
} | ||
|
||
@override | ||
Future<void> dispose() async { | ||
autoUpdater.removeListener(_listener); | ||
|
||
ApplicationInfo.isCriticalUpdateNotifier.removeListener( | ||
_showCriticalUpdateDialog, | ||
); | ||
} | ||
|
||
void _showCriticalUpdateDialog() { | ||
showCustomConfirmDialog( | ||
context: AppGlobals.rootNavKey.currentContext!, | ||
title: LocaleKeys.autoUpdate_criticalUpdateTitle.tr(), | ||
description: LocaleKeys.autoUpdate_criticalUpdateDescription.tr( | ||
namedArgs: { | ||
'currentVersion': ApplicationInfo.applicationVersion, | ||
'newVersion': ApplicationInfo.latestVersion, | ||
}, | ||
), | ||
builder: (context) => const SizedBox.shrink(), | ||
// if the update is critical, dont allow the user to dismiss the dialog | ||
barrierDismissible: false, | ||
showCloseButton: false, | ||
enableKeyboardListener: false, | ||
closeOnConfirm: false, | ||
confirmLabel: LocaleKeys.autoUpdate_criticalUpdateButton.tr(), | ||
onConfirm: () async { | ||
await autoUpdater.checkForUpdates(); | ||
}, | ||
); | ||
} | ||
} | ||
|
||
class _AppFlowyAutoUpdaterListener extends UpdaterListener { | ||
@override | ||
void onUpdaterBeforeQuitForUpdate(AppcastItem? item) {} | ||
|
||
@override | ||
void onUpdaterCheckingForUpdate(Appcast? appcast) { | ||
// Due to the reason documented in the following link, the update will not be found if the user has skipped the update. | ||
// We have to check the skipped version manually. | ||
// https://sparkle-project.org/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(im)checkForUpdateInformation | ||
final items = appcast?.items; | ||
if (items != null) { | ||
final String? currentPlatform; | ||
if (UniversalPlatform.isMacOS) { | ||
currentPlatform = 'macos'; | ||
} else if (UniversalPlatform.isWindows) { | ||
currentPlatform = 'windows'; | ||
} else { | ||
currentPlatform = null; | ||
} | ||
|
||
final matchingItem = items.firstWhereOrNull( | ||
(item) => item.os == currentPlatform, | ||
); | ||
|
||
if (matchingItem != null) { | ||
_updateVersionNotifier(matchingItem); | ||
|
||
Log.info( | ||
'[AutoUpdate] latest version: ${matchingItem.displayVersionString}', | ||
); | ||
} | ||
} | ||
} | ||
|
||
@override | ||
void onUpdaterError(UpdaterError? error) { | ||
Log.error('[AutoUpdate] On update error: $error'); | ||
} | ||
|
||
@override | ||
void onUpdaterUpdateNotAvailable(UpdaterError? error) { | ||
Log.info('[AutoUpdate] Update not available $error'); | ||
} | ||
|
||
@override | ||
void onUpdaterUpdateAvailable(AppcastItem? item) { | ||
_updateVersionNotifier(item); | ||
|
||
Log.info('[AutoUpdate] Update available: ${item?.displayVersionString}'); | ||
} | ||
|
||
@override | ||
void onUpdaterUpdateDownloaded(AppcastItem? item) { | ||
Log.info('[AutoUpdate] Update downloaded: ${item?.displayVersionString}'); | ||
} | ||
|
||
@override | ||
void onUpdaterUpdateCancelled(AppcastItem? item) { | ||
_updateVersionNotifier(item); | ||
|
||
Log.info('[AutoUpdate] Update cancelled: ${item?.displayVersionString}'); | ||
} | ||
|
||
@override | ||
void onUpdaterUpdateInstalled(AppcastItem? item) { | ||
_updateVersionNotifier(item); | ||
|
||
Log.info('[AutoUpdate] Update installed: ${item?.displayVersionString}'); | ||
} | ||
|
||
@override | ||
void onUpdaterUpdateSkipped(AppcastItem? item) { | ||
_updateVersionNotifier(item); | ||
|
||
Log.info('[AutoUpdate] Update skipped: ${item?.displayVersionString}'); | ||
} | ||
|
||
void _updateVersionNotifier(AppcastItem? item) { | ||
if (item != null) { | ||
ApplicationInfo.latestAppcastItem = item; | ||
ApplicationInfo.latestVersionNotifier.value = | ||
item.displayVersionString ?? ''; | ||
} | ||
} | ||
} | ||
|
||
class AppFlowyAutoUpdateVersion { | ||
AppFlowyAutoUpdateVersion({ | ||
required this.latestVersion, | ||
required this.currentVersion, | ||
required this.isForceUpdate, | ||
}); | ||
|
||
factory AppFlowyAutoUpdateVersion.initial() => AppFlowyAutoUpdateVersion( | ||
latestVersion: '0.0.0', | ||
currentVersion: '0.0.0', | ||
isForceUpdate: false, | ||
); | ||
|
||
final String latestVersion; | ||
final String currentVersion; | ||
|
||
final bool isForceUpdate; | ||
|
||
bool get isUpdateAvailable => latestVersion != currentVersion; | ||
} |
Oops, something went wrong.