更改appName等常量为全局变量

This commit is contained in:
rang 2025-11-14 16:34:42 +08:00
parent 896f8837bd
commit e2aa73c01c
35 changed files with 167 additions and 216 deletions

View file

@ -1,6 +1,7 @@
{ {
"cmake.configureOnOpen": false, "cmake.configureOnOpen": false,
"cSpell.words": [ "cSpell.words": [
"Audiobookshelf",
"audioplayers", "audioplayers",
"autolabeler", "autolabeler",
"Autovalidate", "Autovalidate",
@ -13,6 +14,7 @@
"mocktail", "mocktail",
"nodename", "nodename",
"numberpicker", "numberpicker",
"Prefs",
"riverpod", "riverpod",
"Schyler", "Schyler",
"shelfsdk", "shelfsdk",

View file

@ -4,6 +4,8 @@ import 'dart:convert';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
// import 'package:http_cache_core/http_cache_core.dart';
// import 'package:http_cache_isar_store/http_cache_isar_store.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:shelfsdk/audiobookshelf_api.dart'; import 'package:shelfsdk/audiobookshelf_api.dart';
@ -33,6 +35,36 @@ Uri makeBaseUrl(String address) {
return Uri.parse(address); return Uri.parse(address);
} }
// Global options
// final options = CacheOptions(
// // A default store is required for the client.
// store: IsarCacheStore("", name: "http_cache"),
// // All subsequent fields are optional to get a standard behaviour.
// // Default.
// policy: CachePolicy.request,
// // Returns a previous cached response on error for given status codes.
// // Defaults to `[]`.
// hitCacheOnErrorCodes: const [500],
// // Allows to return a cached response on network errors (e.g. offline usage).
// // Defaults to `false`.
// hitCacheOnNetworkFailure: true,
// // Overrides any HTTP directive to delete entry past this duration.
// // Useful only when origin server has no cache config or custom behaviour is desired.
// // Defaults to `null`.
// maxStale: const Duration(days: 7),
// // Default. Allows 3 cache sets and ease cleanup.
// priority: CachePriority.normal,
// // Default. Body and headers encryption with your own algorithm.
// cipher: null,
// // Default. Key builder to retrieve requests.
// keyBuilder: CacheOptions.defaultCacheKeyBuilder,
// // Default. Allows to cache POST requests.
// // Assigning a [keyBuilder] is strongly recommended when `true`.
// allowPostMethod: false,
// );
/// get the api instance for the given base url /// get the api instance for the given base url
@riverpod @riverpod
AudiobookshelfApi audiobookshelfApi(Ref ref, Uri? baseUrl) { AudiobookshelfApi audiobookshelfApi(Ref ref, Uri? baseUrl) {
@ -41,6 +73,7 @@ AudiobookshelfApi audiobookshelfApi(Ref ref, Uri? baseUrl) {
baseUrl ??= apiSettings.activeServer?.serverUrl; baseUrl ??= apiSettings.activeServer?.serverUrl;
return AudiobookshelfApi( return AudiobookshelfApi(
baseUrl: makeBaseUrl(baseUrl.toString()), baseUrl: makeBaseUrl(baseUrl.toString()),
// client:
); );
} }

View file

@ -1,9 +1,9 @@
import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:vaani/settings/constants.dart'; import 'package:vaani/globals.dart';
final imageCacheManager = CacheManager( final imageCacheManager = CacheManager(
Config( Config(
'${AppMetadata.appNameLowerCase}_image_cache', '${appName}_image_cache',
stalePeriod: const Duration(days: 365 * 10), stalePeriod: const Duration(days: 365 * 10),
repo: JsonCacheInfoRepository(), repo: JsonCacheInfoRepository(),
maxNrOfCacheObjects: 1000, maxNrOfCacheObjects: 1000,
@ -12,7 +12,7 @@ final imageCacheManager = CacheManager(
final apiResponseCacheManager = CacheManager( final apiResponseCacheManager = CacheManager(
Config( Config(
'${AppMetadata.appNameLowerCase}_api_response_cache', '${appName}_api_response_cache',
stalePeriod: const Duration(days: 7), stalePeriod: const Duration(days: 7),
repo: JsonCacheInfoRepository(), repo: JsonCacheInfoRepository(),
maxNrOfCacheObjects: 1000, maxNrOfCacheObjects: 1000,

View file

@ -1,27 +1,19 @@
import 'dart:io';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:path/path.dart' as p; import 'package:vaani/globals.dart';
import 'package:path_provider/path_provider.dart';
import 'package:vaani/main.dart';
import 'package:vaani/settings/constants.dart';
import 'register_models.dart'; import 'register_models.dart';
// does the initial setup of the storage // does the initial setup of the storage
Future initStorage() async { Future initStorage() async {
final dir = await getApplicationDocumentsDirectory(); // final dir = await getApplicationDocumentsDirectory();
// use vaani as the directory for hive // // use vaani as the directory for hive
final storageDir = Directory( // final storageDir = Directory(
p.join( // p.join(dir.path, appName),
dir.path, // );
AppMetadata.appNameLowerCase, // await storageDir.create(recursive: true);
),
);
await storageDir.create(recursive: true);
Hive.defaultDirectory = storageDir.path; Hive.defaultDirectory = appStorageDir.path;
appLogger.config('Hive storage directory init: ${Hive.defaultDirectory}'); appLogger.config('Hive storage directory init: ${Hive.defaultDirectory}');
await registerModels(); await registerModels();

View file

@ -19,7 +19,7 @@ import 'package:vaani/features/per_book_settings/providers/book_settings_provide
import 'package:vaani/features/player/providers/audiobook_player.dart'; import 'package:vaani/features/player/providers/audiobook_player.dart';
import 'package:vaani/features/player/providers/player_form.dart'; import 'package:vaani/features/player/providers/player_form.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/router/router.dart'; import 'package:vaani/router/router.dart';
import 'package:vaani/settings/api_settings_provider.dart'; import 'package:vaani/settings/api_settings_provider.dart';
import 'package:vaani/settings/app_settings_provider.dart'; import 'package:vaani/settings/app_settings_provider.dart';

View file

@ -9,7 +9,7 @@ import 'package:vaani/api/library_item_provider.dart';
import 'package:vaani/constants/hero_tag_conventions.dart'; import 'package:vaani/constants/hero_tag_conventions.dart';
import 'package:vaani/features/item_viewer/view/library_item_page.dart'; import 'package:vaani/features/item_viewer/view/library_item_page.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart'; import 'package:vaani/features/player/providers/audiobook_player.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/router/models/library_item_extras.dart'; import 'package:vaani/router/models/library_item_extras.dart';
import 'package:vaani/settings/app_settings_provider.dart'; import 'package:vaani/settings/app_settings_provider.dart';
import 'package:vaani/shared/extensions/duration_format.dart'; import 'package:vaani/shared/extensions/duration_format.dart';
@ -369,9 +369,10 @@ class _BookCover extends HookConsumerWidget {
builder: (context) { builder: (context) {
// change theme after 2 seconds // change theme after 2 seconds
if (themeSettings.useMaterialThemeOnItemPage) { if (themeSettings.useMaterialThemeOnItemPage) {
final theme = ThemeSwitcher.of(context);
Future.delayed(150.ms, () { Future.delayed(150.ms, () {
try { try {
ThemeSwitcher.of(context).changeTheme( theme.changeTheme(
theme: coverColorScheme != null theme: coverColorScheme != null
? ThemeData.from( ? ThemeData.from(
colorScheme: coverColorScheme, colorScheme: coverColorScheme,

View file

@ -1,14 +1,12 @@
import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:logging_appenders/logging_appenders.dart'; import 'package:logging_appenders/logging_appenders.dart';
import 'package:path_provider/path_provider.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/shared/extensions/duration_format.dart'; import 'package:vaani/shared/extensions/duration_format.dart';
Future<String> getLoggingFilePath() async { Future<String> getLoggingFilePath() async {
final Directory directory = await getApplicationDocumentsDirectory(); // final Directory directory = await getApplicationDocumentsDirectory();
return '${directory.path}/vaani.log'; return '${appStorageDir.path}/$appName.log';
} }
Future<void> initLogging() async { Future<void> initLogging() async {

View file

@ -4,7 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:share_plus/share_plus.dart'; import 'package:share_plus/share_plus.dart';
import 'package:vaani/features/logging/providers/logs_provider.dart'; import 'package:vaani/features/logging/providers/logs_provider.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
class LogsPage extends HookConsumerWidget { class LogsPage extends HookConsumerWidget {
const LogsPage({super.key}); const LogsPage({super.key});

View file

@ -5,8 +5,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/api/api_provider.dart'; import 'package:vaani/api/api_provider.dart';
import 'package:vaani/features/onboarding/view/user_login.dart'; import 'package:vaani/features/onboarding/view/user_login.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/globals.dart';
import 'package:vaani/settings/api_settings_provider.dart'; import 'package:vaani/settings/api_settings_provider.dart';
import 'package:vaani/settings/constants.dart';
import 'package:vaani/shared/utils.dart'; import 'package:vaani/shared/utils.dart';
import 'package:vaani/shared/widgets/add_new_server.dart'; import 'package:vaani/shared/widgets/add_new_server.dart';
@ -79,7 +79,7 @@ class OnboardingBody extends HookConsumerWidget {
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
S.of(context).loginTitle(AppMetadata.appName), S.of(context).loginTitle(appName),
style: Theme.of(context).textTheme.headlineSmall, style: Theme.of(context).textTheme.headlineSmall,
), ),
), ),

View file

@ -6,10 +6,9 @@ import 'package:shelfsdk/audiobookshelf_api.dart';
import 'package:vaani/api/api_provider.dart'; import 'package:vaani/api/api_provider.dart';
import 'package:vaani/features/onboarding/providers/oauth_provider.dart'; import 'package:vaani/features/onboarding/providers/oauth_provider.dart';
import 'package:vaani/features/onboarding/view/user_login_with_password.dart'; import 'package:vaani/features/onboarding/view/user_login_with_password.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/models/error_response.dart'; import 'package:vaani/models/error_response.dart';
import 'package:vaani/router/router.dart'; import 'package:vaani/router/router.dart';
import 'package:vaani/settings/constants.dart';
import 'package:vaani/settings/models/models.dart' as model; import 'package:vaani/settings/models/models.dart' as model;
import 'package:vaani/shared/extensions/obfuscation.dart'; import 'package:vaani/shared/extensions/obfuscation.dart';
import 'package:vaani/shared/utils.dart'; import 'package:vaani/shared/utils.dart';
@ -40,9 +39,9 @@ class UserLoginWithOpenID extends HookConsumerWidget {
appLogger.fine('Generated verifier: $verifier\nchallenge: $challenge'); appLogger.fine('Generated verifier: $verifier\nchallenge: $challenge');
final appRedirectUri = final appRedirectUri =
'${AppMetadata.appScheme}://${Routes.openIDCallback.fullPath.substring(1)}'; '$appScheme://${Routes.openIDCallback.fullPath.substring(1)}';
final (openIDLoginEndpoint, authCookie) = await api.server.oauth2Request( final (openIDLoginEndpoint, authCookie) = await api.server.oauth2Request(
clientId: AppMetadata.appName, clientId: appName,
codeChallenge: challenge, codeChallenge: challenge,
// redirectUri: Uri( // redirectUri: Uri(
// scheme: AppMetadata.appScheme, // scheme: AppMetadata.appScheme,

View file

@ -7,10 +7,10 @@ import 'package:shelfsdk/audiobookshelf_api.dart';
import 'package:vaani/api/api_provider.dart'; import 'package:vaani/api/api_provider.dart';
import 'package:vaani/api/authenticated_users_provider.dart'; import 'package:vaani/api/authenticated_users_provider.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/globals.dart';
import 'package:vaani/hacks/fix_autofill_losing_focus.dart'; import 'package:vaani/hacks/fix_autofill_losing_focus.dart';
import 'package:vaani/models/error_response.dart'; import 'package:vaani/models/error_response.dart';
import 'package:vaani/router/router.dart'; import 'package:vaani/router/router.dart';
import 'package:vaani/settings/constants.dart';
import 'package:vaani/settings/models/models.dart' as model; import 'package:vaani/settings/models/models.dart' as model;
import 'package:vaani/shared/utils.dart'; import 'package:vaani/shared/utils.dart';
@ -214,10 +214,10 @@ Future<void> handleServerError(
onPressed: () { onPressed: () {
// open an issue on the github page // open an issue on the github page
handleLaunchUrl( handleLaunchUrl(
AppMetadata.githubRepo githubRepo
// append the issue url // append the issue url
.replace( .replace(
path: '${AppMetadata.githubRepo.path}/issues/new', path: '${githubRepo.path}/issues/new',
), ),
); );
}, },

View file

@ -1,11 +1,10 @@
import 'package:package_info_plus/package_info_plus.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:vaani/api/api_provider.dart'; import 'package:vaani/api/api_provider.dart';
import 'package:vaani/features/playback_reporting/core/playback_reporter.dart' import 'package:vaani/features/playback_reporting/core/playback_reporter.dart'
as core; as core;
import 'package:vaani/features/player/providers/audiobook_player.dart'; import 'package:vaani/features/player/providers/audiobook_player.dart';
import 'package:vaani/globals.dart';
import 'package:vaani/settings/app_settings_provider.dart'; import 'package:vaani/settings/app_settings_provider.dart';
import 'package:vaani/settings/metadata/metadata_provider.dart';
part 'playback_reporter_provider.g.dart'; part 'playback_reporter_provider.g.dart';
@ -15,13 +14,7 @@ class PlaybackReporter extends _$PlaybackReporter {
Future<core.PlaybackReporter> build() async { Future<core.PlaybackReporter> build() async {
final playerSettings = ref.watch(appSettingsProvider).playerSettings; final playerSettings = ref.watch(appSettingsProvider).playerSettings;
final player = ref.watch(simpleAudiobookPlayerProvider); final player = ref.watch(simpleAudiobookPlayerProvider);
final packageInfo = await PackageInfo.fromPlatform();
final api = ref.watch(authenticatedApiProvider); final api = ref.watch(authenticatedApiProvider);
final deviceName = await ref.watch(deviceNameProvider.future);
final deviceModel = await ref.watch(deviceModelProvider.future);
final deviceSdkVersion = await ref.watch(deviceSdkVersionProvider.future);
final deviceManufacturer =
await ref.watch(deviceManufacturerProvider.future);
final reporter = core.PlaybackReporter( final reporter = core.PlaybackReporter(
player, player,
@ -32,8 +25,8 @@ class PlaybackReporter extends _$PlaybackReporter {
deviceName: deviceName, deviceName: deviceName,
deviceModel: deviceModel, deviceModel: deviceModel,
deviceSdkVersion: deviceSdkVersion, deviceSdkVersion: deviceSdkVersion,
deviceClientName: packageInfo.appName, deviceClientName: appName,
deviceClientVersion: packageInfo.version, deviceClientVersion: appVersion,
deviceManufacturer: deviceManufacturer, deviceManufacturer: deviceManufacturer,
); );
ref.onDispose(reporter.dispose); ref.onDispose(reporter.dispose);

View file

@ -6,7 +6,7 @@ part of 'playback_reporter_provider.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$playbackReporterHash() => r'f5436d652e51c37bcc684acdaec94e17a97e68e5'; String _$playbackReporterHash() => r'43bde2ac163830b6950303a80cdd915ffcb1943b';
/// See also [PlaybackReporter]. /// See also [PlaybackReporter].
@ProviderFor(PlaybackReporter) @ProviderFor(PlaybackReporter)

View file

@ -9,7 +9,7 @@ import 'package:vaani/settings/models/app_settings.dart';
Future<void> configurePlayer() async { Future<void> configurePlayer() async {
// for playing audio on windows, linux // for playing audio on windows, linux
JustAudioMediaKit.ensureInitialized(); JustAudioMediaKit.ensureInitialized(windows: false);
// for configuring how this app will interact with other audio apps // for configuring how this app will interact with other audio apps
final session = await AudioSession.instance; final session = await AudioSession.instance;

View file

@ -8,7 +8,7 @@ import 'package:vaani/features/player/providers/currently_playing_provider.dart'
import 'package:vaani/features/player/view/player_expanded.dart' import 'package:vaani/features/player/view/player_expanded.dart'
show pendingPlayerModals; show pendingPlayerModals;
import 'package:vaani/features/player/view/widgets/playing_indicator_icon.dart'; import 'package:vaani/features/player/view/widgets/playing_indicator_icon.dart';
import 'package:vaani/main.dart' show appLogger; import 'package:vaani/globals.dart';
import 'package:vaani/shared/extensions/chapter.dart' show ChapterDuration; import 'package:vaani/shared/extensions/chapter.dart' show ChapterDuration;
import 'package:vaani/shared/extensions/duration_format.dart' import 'package:vaani/shared/extensions/duration_format.dart'
show DurationFormat; show DurationFormat;

View file

@ -7,7 +7,7 @@ import 'package:vaani/features/player/view/widgets/speed_selector.dart';
import 'package:vaani/features/sleep_timer/core/sleep_timer.dart'; import 'package:vaani/features/sleep_timer/core/sleep_timer.dart';
import 'package:vaani/features/sleep_timer/providers/sleep_timer_provider.dart' import 'package:vaani/features/sleep_timer/providers/sleep_timer_provider.dart'
show sleepTimerProvider; show sleepTimerProvider;
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/settings/app_settings_provider.dart'; import 'package:vaani/settings/app_settings_provider.dart';
import 'package:vaani/shared/extensions/duration_format.dart'; import 'package:vaani/shared/extensions/duration_format.dart';

View file

@ -12,7 +12,7 @@ import 'package:vaani/features/onboarding/view/user_login.dart'
import 'package:vaani/features/player/view/mini_player_bottom_padding.dart' import 'package:vaani/features/player/view/mini_player_bottom_padding.dart'
show MiniPlayerBottomPadding; show MiniPlayerBottomPadding;
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/main.dart' show appLogger; import 'package:vaani/globals.dart';
import 'package:vaani/router/router.dart' show Routes; import 'package:vaani/router/router.dart' show Routes;
import 'package:vaani/settings/api_settings_provider.dart' import 'package:vaani/settings/api_settings_provider.dart'
show apiSettingsProvider; show apiSettingsProvider;

View file

@ -1,15 +1,15 @@
import 'dart:io' show Platform;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shelfsdk/audiobookshelf_api.dart' show Library; import 'package:shelfsdk/audiobookshelf_api.dart' show Library;
import 'package:vaani/api/library_provider.dart'; import 'package:vaani/api/library_provider.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/globals.dart';
import 'package:vaani/settings/api_settings_provider.dart' import 'package:vaani/settings/api_settings_provider.dart'
show apiSettingsProvider; show apiSettingsProvider;
import 'package:vaani/shared/icons/abs_icons.dart'; import 'package:vaani/shared/icons/abs_icons.dart';
import 'dart:io' show Platform;
import 'package:flutter/foundation.dart';
import 'package:vaani/main.dart' show appLogger;
class LibrarySwitchChip extends HookConsumerWidget { class LibrarySwitchChip extends HookConsumerWidget {
const LibrarySwitchChip({ const LibrarySwitchChip({

View file

@ -6,8 +6,8 @@ import 'package:vaani/api/library_provider.dart' show librariesProvider;
import 'package:vaani/features/player/view/mini_player_bottom_padding.dart'; import 'package:vaani/features/player/view/mini_player_bottom_padding.dart';
import 'package:vaani/features/you/view/widgets/library_switch_chip.dart'; import 'package:vaani/features/you/view/widgets/library_switch_chip.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/globals.dart';
import 'package:vaani/router/router.dart'; import 'package:vaani/router/router.dart';
import 'package:vaani/settings/constants.dart';
import 'package:vaani/shared/utils.dart'; import 'package:vaani/shared/utils.dart';
import 'package:vaani/shared/widgets/not_implemented.dart'; import 'package:vaani/shared/widgets/not_implemented.dart';
import 'package:vaani/shared/widgets/vaani_logo.dart'; import 'package:vaani/shared/widgets/vaani_logo.dart';
@ -141,17 +141,16 @@ class YouPage extends HookConsumerWidget {
), ),
AboutListTile( AboutListTile(
icon: const Icon(Icons.info), icon: const Icon(Icons.info),
applicationName: AppMetadata.appName, applicationName: appName,
applicationVersion: AppMetadata.version, applicationVersion: appVersion,
applicationLegalese: applicationLegalese: 'Made with ❤️ by $appAuthor',
'Made with ❤️ by ${AppMetadata.author}',
aboutBoxChildren: [ aboutBoxChildren: [
// link to github repo // link to github repo
ListTile( ListTile(
leading: Icon(Icons.code), leading: Icon(Icons.code),
title: Text('Source Code'), title: Text('Source Code'),
onTap: () { onTap: () {
handleLaunchUrl(AppMetadata.githubRepo); handleLaunchUrl(githubRepo);
}, },
), ),
], ],

View file

@ -1,18 +1,53 @@
//
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:logging/logging.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
part 'metadata_provider.g.dart'; late String appName;
const String appScheme = "vaani";
late String appVersion;
const String appAuthor = "rang";
late String appBuildNumber;
@Riverpod(keepAlive: true) Uri githubRepo = Uri.parse('https://github.com/rangdl/Vaani');
Future<String> deviceName(Ref ref) async {
final data = await _getDeviceData(DeviceInfoPlugin());
Future<void> initialize() async {
final packageInfo = await PackageInfo.fromPlatform();
appName = packageInfo.appName;
appVersion = packageInfo.version;
appBuildNumber = packageInfo.buildNumber;
deviceData = await _getDeviceData(DeviceInfoPlugin());
deviceName = getDeviceName(deviceData);
deviceModel = getDeviceModel(deviceData);
deviceSdkVersion = getDeviceSdkVersion(deviceData);
deviceManufacturer = getDeviceManufacturer(deviceData);
appLogger = Logger(appName);
final dir = await getApplicationDocumentsDirectory();
appStorageDir = Directory(
p.join(dir.path, appName),
);
await appStorageDir.create(recursive: true);
}
late Map<String, dynamic> deviceData;
late String deviceName;
late String deviceModel;
late String deviceSdkVersion;
late String deviceManufacturer;
late Logger appLogger;
late Directory appStorageDir;
String getDeviceName(data) {
// try different keys to get the device name // try different keys to get the device name
return return // android
// android
data['product'] ?? data['product'] ??
// ios // ios
data['name'] ?? data['name'] ??
@ -27,10 +62,7 @@ Future<String> deviceName(Ref ref) async {
'Unknown name'; 'Unknown name';
} }
@Riverpod(keepAlive: true) String getDeviceModel(data) {
Future<String> deviceModel(Ref ref) async {
final data = await _getDeviceData(DeviceInfoPlugin());
// try different keys to get the device model // try different keys to get the device model
return return
// android, eg: Google Pixel 4 // android, eg: Google Pixel 4
@ -48,10 +80,7 @@ Future<String> deviceModel(Ref ref) async {
'Unknown model'; 'Unknown model';
} }
@Riverpod(keepAlive: true) String getDeviceSdkVersion(data) {
Future<String> deviceSdkVersion(Ref ref) async {
final data = await _getDeviceData(DeviceInfoPlugin());
// try different keys to get the device sdk version // try different keys to get the device sdk version
return return
// android, eg: 30 // android, eg: 30
@ -69,10 +98,7 @@ Future<String> deviceSdkVersion(Ref ref) async {
'Unknown sdk version'; 'Unknown sdk version';
} }
@Riverpod(keepAlive: true) String getDeviceManufacturer(data) {
Future<String> deviceManufacturer(Ref ref) async {
final data = await _getDeviceData(DeviceInfoPlugin());
// try different keys to get the device manufacturer // try different keys to get the device manufacturer
return return
// android, eg: Google // android, eg: Google

View file

@ -2,32 +2,28 @@ import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:logging/logging.dart';
import 'package:vaani/api/server_provider.dart'; import 'package:vaani/api/server_provider.dart';
import 'package:vaani/db/storage.dart'; import 'package:vaani/db/storage.dart';
import 'package:vaani/features/downloads/providers/download_manager.dart'; import 'package:vaani/features/downloads/providers/download_manager.dart';
import 'package:vaani/features/logging/core/logger.dart'; import 'package:vaani/features/logging/core/logger.dart';
import 'package:vaani/features/playback_reporting/providers/playback_reporter_provider.dart'; import 'package:vaani/features/playback_reporting/providers/playback_reporter_provider.dart';
import 'package:vaani/features/player/core/init.dart'; import 'package:vaani/features/player/core/init.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart' import 'package:vaani/features/player/providers/audiobook_player.dart';
show audiobookPlayerProvider, simpleAudiobookPlayerProvider;
import 'package:vaani/features/shake_detection/providers/shake_detector.dart'; import 'package:vaani/features/shake_detection/providers/shake_detector.dart';
import 'package:vaani/features/skip_start_end/skip_start_end_provider.dart'; import 'package:vaani/features/skip_start_end/skip_start_end_provider.dart';
import 'package:vaani/features/sleep_timer/providers/sleep_timer_provider.dart'; import 'package:vaani/features/sleep_timer/providers/sleep_timer_provider.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/globals.dart';
import 'package:vaani/models/tray.dart'; import 'package:vaani/models/tray.dart';
import 'package:vaani/router/router.dart'; import 'package:vaani/router/router.dart';
import 'package:vaani/settings/api_settings_provider.dart'; import 'package:vaani/settings/api_settings_provider.dart';
import 'package:vaani/settings/app_settings_provider.dart'; import 'package:vaani/settings/app_settings_provider.dart';
import 'package:vaani/settings/settings.dart';
import 'package:vaani/shared/utils/utils.dart'; import 'package:vaani/shared/utils/utils.dart';
import 'package:vaani/theme/providers/system_theme_provider.dart'; import 'package:vaani/theme/providers/system_theme_provider.dart';
import 'package:vaani/theme/providers/theme_from_cover_provider.dart'; import 'package:vaani/theme/providers/theme_from_cover_provider.dart';
import 'package:vaani/theme/theme.dart'; import 'package:vaani/theme/theme.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
final appLogger = Logger(AppMetadata.appName);
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
@ -43,6 +39,9 @@ void main() async {
await windowManager.setPreventClose(true); await windowManager.setPreventClose(true);
}); });
} }
// Configure the App Metadata
await initialize();
// Configure the root Logger // Configure the root Logger
await initLogging(); await initLogging();
@ -55,15 +54,15 @@ void main() async {
// run the app // run the app
runApp( runApp(
const ProviderScope( const ProviderScope(
child: _EagerInitialization(child: TrayFramework(MyApp())), child: _EagerInitialization(child: TrayFramework(AbsApp())),
), ),
); );
} }
var routerConfig = const MyAppRouter().config; var routerConfig = const MyAppRouter().config;
class MyApp extends ConsumerWidget { class AbsApp extends ConsumerWidget {
const MyApp({super.key}); const AbsApp({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:tray_manager/tray_manager.dart'; import 'package:tray_manager/tray_manager.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart'; import 'package:vaani/features/player/providers/audiobook_player.dart';
import 'package:vaani/settings/constants.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/shared/utils/utils.dart'; import 'package:vaani/shared/utils/utils.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
@ -36,7 +36,7 @@ class _TrayFrameworkState extends ConsumerState<TrayFramework>
await trayManager.setIcon( await trayManager.setIcon(
Utils.isWindows() ? 'assets/icon/logo.ico' : 'assets/icon/logo.png', Utils.isWindows() ? 'assets/icon/logo.ico' : 'assets/icon/logo.png',
); );
await trayManager.setToolTip(AppMetadata.appName); await trayManager.setToolTip(appName);
Menu menu = Menu( Menu menu = Menu(
items: [ items: [
MenuItem( MenuItem(

View file

@ -4,12 +4,11 @@ import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/api/api_provider.dart'; import 'package:vaani/api/api_provider.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/router/router.dart'; import 'package:vaani/router/router.dart';
import 'package:vaani/settings/api_settings_provider.dart'; import 'package:vaani/settings/api_settings_provider.dart';
import 'package:vaani/settings/app_settings_provider.dart' import 'package:vaani/settings/app_settings_provider.dart'
show appSettingsProvider; show appSettingsProvider;
import 'package:vaani/settings/constants.dart';
import '../shared/widgets/shelves/home_shelf.dart'; import '../shared/widgets/shelves/home_shelf.dart';
@ -28,7 +27,7 @@ class HomePage extends HookConsumerWidget {
appBar: AppBar( appBar: AppBar(
title: GestureDetector( title: GestureDetector(
child: Text( child: Text(
AppMetadata.appName, appName,
style: Theme.of(context).textTheme.headlineLarge, style: Theme.of(context).textTheme.headlineLarge,
), ),
onTap: () { onTap: () {

View file

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/api/api_provider.dart'; import 'package:vaani/api/api_provider.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/settings/api_settings_provider.dart'; import 'package:vaani/settings/api_settings_provider.dart';
import '../shared/widgets/drawer.dart'; import '../shared/widgets/drawer.dart';

View file

@ -11,15 +11,15 @@ import 'package:vaani/features/onboarding/view/onboarding_single_page.dart';
import 'package:vaani/features/player/view/player_expanded.dart'; import 'package:vaani/features/player/view/player_expanded.dart';
import 'package:vaani/features/you/view/server_manager.dart'; import 'package:vaani/features/you/view/server_manager.dart';
import 'package:vaani/features/you/view/you_page.dart'; import 'package:vaani/features/you/view/you_page.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/pages/home_page.dart'; import 'package:vaani/pages/home_page.dart';
import 'package:vaani/settings/view/app_settings_page.dart'; import 'package:vaani/settings/view/app_settings_page.dart';
import 'package:vaani/settings/view/auto_sleep_timer_settings_page.dart'; import 'package:vaani/settings/view/auto_sleep_timer_settings_page.dart';
import 'package:vaani/settings/view/home_page_settings_page.dart';
import 'package:vaani/settings/view/notification_settings_page.dart'; import 'package:vaani/settings/view/notification_settings_page.dart';
import 'package:vaani/settings/view/player_settings_page.dart'; import 'package:vaani/settings/view/player_settings_page.dart';
import 'package:vaani/settings/view/shake_detector_settings_page.dart'; import 'package:vaani/settings/view/shake_detector_settings_page.dart';
import 'package:vaani/settings/view/theme_settings_page.dart'; import 'package:vaani/settings/view/theme_settings_page.dart';
import 'package:vaani/settings/view/home_page_settings_page.dart';
import 'scaffold_with_nav_bar.dart'; import 'scaffold_with_nav_bar.dart';
import 'transitions/slide.dart'; import 'transitions/slide.dart';

View file

@ -7,7 +7,7 @@ import 'package:vaani/features/player/providers/player_form.dart';
import 'package:vaani/features/player/view/player_minimized.dart'; import 'package:vaani/features/player/view/player_minimized.dart';
import 'package:vaani/features/you/view/widgets/library_switch_chip.dart'; import 'package:vaani/features/you/view/widgets/library_switch_chip.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/router/router.dart'; import 'package:vaani/router/router.dart';
import 'package:vaani/shared/icons/abs_icons.dart' show AbsIcons; import 'package:vaani/shared/icons/abs_icons.dart' show AbsIcons;
import 'package:vaani/shared/utils/utils.dart'; import 'package:vaani/shared/utils/utils.dart';

View file

@ -1,18 +0,0 @@
import 'package:flutter/foundation.dart' show immutable;
@immutable
class AppMetadata {
const AppMetadata._();
// TODO: use the packageinfo package to get the app name
static const String appName = 'Vaani';
// for deeplinking
static const String appScheme = 'vaani';
static const version = '1.0.0';
static const author = 'Dr.Blank';
static Uri githubRepo = Uri.parse('https://github.com/Dr-Blank/Vaani');
static get appNameLowerCase => appName.toLowerCase().replaceAll(' ', '_');
}

View file

@ -1,77 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'metadata_provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$deviceNameHash() => r'9e38adda74e70a91851a682f05228bd759356dcc';
/// See also [deviceName].
@ProviderFor(deviceName)
final deviceNameProvider = FutureProvider<String>.internal(
deviceName,
name: r'deviceNameProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$deviceNameHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef DeviceNameRef = FutureProviderRef<String>;
String _$deviceModelHash() => r'922b13d9e35b5b5c5b8e96f2f2c2ae594f4f41f2';
/// See also [deviceModel].
@ProviderFor(deviceModel)
final deviceModelProvider = FutureProvider<String>.internal(
deviceModel,
name: r'deviceModelProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$deviceModelHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef DeviceModelRef = FutureProviderRef<String>;
String _$deviceSdkVersionHash() => r'33178d80590808d1f4cca2be8a3b52c6f6724cac';
/// See also [deviceSdkVersion].
@ProviderFor(deviceSdkVersion)
final deviceSdkVersionProvider = FutureProvider<String>.internal(
deviceSdkVersion,
name: r'deviceSdkVersionProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$deviceSdkVersionHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef DeviceSdkVersionRef = FutureProviderRef<String>;
String _$deviceManufacturerHash() =>
r'39250767deb8635fa7c7e18bae23576b9b863e04';
/// See also [deviceManufacturer].
@ProviderFor(deviceManufacturer)
final deviceManufacturerProvider = FutureProvider<String>.internal(
deviceManufacturer,
name: r'deviceManufacturerProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$deviceManufacturerHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef DeviceManufacturerRef = FutureProviderRef<String>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

View file

@ -1,2 +1 @@
export 'app_settings_provider.dart'; export 'app_settings_provider.dart';
export 'constants.dart';

View file

@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/api/api_provider.dart'; import 'package:vaani/api/api_provider.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/main.dart'; import 'package:vaani/globals.dart';
final httpUrlRegExp = RegExp('https?://'); final httpUrlRegExp = RegExp('https?://');

View file

@ -94,11 +94,15 @@ class ExpandableDescription extends HookWidget {
child: Html( child: Html(
data: '<div class="vaani-ellipsis">$content</div>', data: '<div class="vaani-ellipsis">$content</div>',
style: { style: {
"div": Style( "div.vaani-ellipsis": !isDescExpanded.value
maxLines: isDescExpanded.value ? null : 3, ? Style(
textOverflow: TextOverflow.ellipsis, maxLines: 3,
fontStyle: textTheme.bodyMedium?.fontStyle, textOverflow: TextOverflow.ellipsis,
), fontStyle: textTheme.bodyMedium?.fontStyle,
)
: Style(
fontStyle: textTheme.bodyMedium?.fontStyle,
),
}, },
), ),
), ),

View file

@ -787,6 +787,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.16" version: "0.4.16"
just_audio_windows:
dependency: "direct main"
description:
name: just_audio_windows
sha256: b1ba5305d841c0e3883644e20fc11aaa23f28cfdd43ec20236d1e119a402ef29
url: "https://pub.dev"
source: hosted
version: "0.2.2"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
@ -899,14 +907,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
media_kit_libs_windows_audio:
dependency: "direct main"
description:
name: media_kit_libs_windows_audio
sha256: c2fd558cc87b9d89a801141fcdffe02e338a3b21a41a18fbd63d5b221a1b8e53
url: "https://pub.dev"
source: hosted
version: "1.0.9"
menu_base: menu_base:
dependency: transitive dependency: transitive
description: description:

View file

@ -69,10 +69,10 @@ dependencies:
url: https://github.com/Dr-Blank/just_audio url: https://github.com/Dr-Blank/just_audio
ref: media-notification-config ref: media-notification-config
path: just_audio_background path: just_audio_background
# just_audio_windows: ^0.2.2 just_audio_windows: ^0.2.2
just_audio_media_kit: ^2.0.4 just_audio_media_kit: ^2.0.4
media_kit_libs_linux: any media_kit_libs_linux: any
media_kit_libs_windows_audio: any # media_kit_libs_windows_audio: any
list_wheel_scroll_view_nls: ^0.0.3 list_wheel_scroll_view_nls: ^0.0.3
logging: ^1.2.0 logging: ^1.2.0
logging_appenders: ^1.3.1 logging_appenders: ^1.3.1
@ -102,6 +102,8 @@ dependencies:
sdk: flutter sdk: flutter
window_manager: ^0.5.1 window_manager: ^0.5.1
tray_manager: ^0.5.2 tray_manager: ^0.5.2
# http_cache_client: ^1.0.4
# http_cache_isar_store: ^3.0.0-dev.1
dev_dependencies: dev_dependencies:
build_runner: ^2.4.9 build_runner: ^2.4.9
custom_lint: ^0.7.0 custom_lint: ^0.7.0

View file

@ -8,7 +8,7 @@
#include <dynamic_color/dynamic_color_plugin_c_api.h> #include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <isar_flutter_libs/isar_flutter_libs_plugin.h> #include <isar_flutter_libs/isar_flutter_libs_plugin.h>
#include <media_kit_libs_windows_audio/media_kit_libs_windows_audio_plugin_c_api.h> #include <just_audio_windows/just_audio_windows_plugin.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h> #include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
#include <share_plus/share_plus_windows_plugin_c_api.h> #include <share_plus/share_plus_windows_plugin_c_api.h>
@ -21,8 +21,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
IsarFlutterLibsPluginRegisterWithRegistrar( IsarFlutterLibsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin")); registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin"));
MediaKitLibsWindowsAudioPluginCApiRegisterWithRegistrar( JustAudioWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("MediaKitLibsWindowsAudioPluginCApi")); registry->GetRegistrarForPlugin("JustAudioWindowsPlugin"));
PermissionHandlerWindowsPluginRegisterWithRegistrar( PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar( ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(

View file

@ -5,7 +5,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color dynamic_color
isar_flutter_libs isar_flutter_libs
media_kit_libs_windows_audio just_audio_windows
permission_handler_windows permission_handler_windows
screen_retriever_windows screen_retriever_windows
share_plus share_plus