Compare commits

...

5 commits

Author SHA1 Message Date
github-actions[bot]
f569041ab3 chore(release): bump version to v0.0.17
Some checks are pending
Flutter CI & Release / Test (push) Waiting to run
Flutter CI & Release / Build Android APKs (push) Blocked by required conditions
Flutter CI & Release / build_linux (push) Blocked by required conditions
Flutter CI & Release / Create GitHub Release (push) Blocked by required conditions
2025-04-10 14:22:52 +00:00
Dr.Blank
39d051746b
update label regex 2025-04-10 19:46:57 +05:30
Dr.Blank
4ebf46d2fd
chore: remove deprecated apis (#74)
* dart format + remove withopacity

* remove unused imports
2025-04-10 19:42:08 +05:30
Dr.Blank
4af16ac5b4
ci: add format check for lib/ 2025-04-10 19:38:18 +05:30
Dr.Blank
28ceca5408
fix: bug login not shown for some languages (#73)
* fix language preventing logging in

* make eye blink once
2025-04-10 19:12:20 +05:30
27 changed files with 214 additions and 169 deletions

View file

@ -40,7 +40,7 @@ template: |
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
exclude-labels:
- "skip-changelog"
- "skip changelog"
exclude-contributors:
- "Dr-Blank"
@ -55,15 +55,15 @@ autolabeler:
branch:
- '/feature\/.+/'
title:
- "/feat(ure)?/i"
- "/^feat(ure)?/i"
body:
- "/JIRA-[0-9]{1,4}/"
- label: "chore"
title:
- "/chore/i"
- "/^chore\b/i"
- label: "ui"
title:
- "/^ui\b/i"
- label: "refactor"
title:
- "/refactor/i"
- "/^refactor/i"

View file

@ -48,6 +48,10 @@ jobs:
# - name: Run static analysis
# run: flutter analyze
- name: Check formatting
run: |
dart format -o none --set-exit-if-changed lib/
- name: Run tests
run: flutter test

View file

@ -10,5 +10,4 @@ class HeroTagPrefixes {
static const String bookTitle = 'book_title_';
static const String narratorName = 'narrator_name_';
static const String libraryItemPlayButton = 'library_item_play_button_';
}

View file

@ -98,8 +98,10 @@ class MySearchBar extends HookConsumerWidget {
// opacity: 0.5 for the hint text
hintStyle: WidgetStatePropertyAll(
Theme.of(context).textTheme.bodyMedium!.copyWith(
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.5),
),
),
textInputAction: TextInputAction.search,

View file

@ -199,8 +199,10 @@ class _LibraryItemProgressIndicator extends HookConsumerWidget {
'${remainingTime.smartBinaryFormat} left',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.75),
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.75),
),
),
],
@ -227,7 +229,7 @@ class _HeroSectionSubLabelWithIcon extends HookConsumerWidget {
ref.watch(appSettingsProvider).themeSettings.useMaterialThemeOnItemPage;
final color = useMaterialThemeOnItemPage
? themeData.colorScheme.primary
: themeData.colorScheme.onSurface.withOpacity(0.75);
: themeData.colorScheme.onSurface.withValues(alpha: 0.75);
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Row(
@ -443,7 +445,7 @@ class _BookTitle extends StatelessWidget {
? const SizedBox.shrink()
: Text(
style: themeData.textTheme.titleSmall?.copyWith(
color: themeData.colorScheme.onSurface.withOpacity(0.8),
color: themeData.colorScheme.onSurface.withValues(alpha: 0.8),
),
itemBookMetadata?.subtitle ?? '',
),

View file

@ -96,7 +96,10 @@ class LibraryItemMetadata extends HookConsumerWidget {
return VerticalDivider(
indent: 6,
endIndent: 6,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.6),
);
},
),
@ -125,7 +128,7 @@ class _MetadataItem extends StatelessWidget {
children: [
Text(
style: themeData.textTheme.titleMedium?.copyWith(
color: themeData.colorScheme.onSurface.withOpacity(0.90),
color: themeData.colorScheme.onSurface.withValues(alpha: 0.90),
),
value,
maxLines: 1,
@ -133,7 +136,7 @@ class _MetadataItem extends StatelessWidget {
),
Text(
style: themeData.textTheme.bodySmall?.copyWith(
color: themeData.colorScheme.onSurface.withOpacity(0.7),
color: themeData.colorScheme.onSurface.withValues(alpha: 0.7),
),
title,
maxLines: 1,

View file

@ -13,6 +13,37 @@ class OnboardingSinglePage extends HookConsumerWidget {
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Center(
child: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: 600,
minWidth:
constraints.maxWidth < 600 ? constraints.maxWidth : 0,
),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: SafeArea(child: OnboardingBody()),
),
),
),
);
},
),
);
}
}
class OnboardingBody extends HookConsumerWidget {
const OnboardingBody({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final apiSettings = ref.watch(apiSettingsProvider);
@ -39,65 +70,65 @@ class OnboardingSinglePage extends HookConsumerWidget {
);
}
return Scaffold(
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Welcome to Vaani',
style: Theme.of(context).textTheme.headlineSmall,
),
),
const SizedBox.square(
dimension: 16.0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: AnimatedSwitcher(
duration: 500.ms,
transitionBuilder: fadeSlideTransitionBuilder,
child: canUserLogin.value
? Text(
'Server connected, please login',
key: const ValueKey('connected'),
style: Theme.of(context).textTheme.bodyMedium,
)
: Text(
'Please enter the URL of your AudiobookShelf Server',
key: const ValueKey('not_connected'),
style: Theme.of(context).textTheme.bodyMedium,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: AddNewServer(
controller: serverUriController,
allowEmpty: true,
onPressed: () {
canUserLogin.value = serverUriController.text.isNotEmpty;
},
),
),
AnimatedSwitcher(
duration: 500.ms,
transitionBuilder: fadeSlideTransitionBuilder,
child: canUserLogin.value
? UserLoginWidget(
server: audiobookshelfUri,
)
// ).animate().fade(duration: 600.ms).slideY(begin: 0.3, end: 0)
: const RedirectToABS().animate().fadeIn().slideY(
curve: Curves.easeInOut,
duration: 500.ms,
),
),
],
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Welcome to Vaani',
style: Theme.of(context).textTheme.headlineSmall,
),
),
),
const SizedBox.square(
dimension: 16.0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: AnimatedSwitcher(
duration: 500.ms,
transitionBuilder: fadeSlideTransitionBuilder,
child: canUserLogin.value
? Text(
'Server connected, please login',
key: const ValueKey('connected'),
style: Theme.of(context).textTheme.bodyMedium,
)
: Text(
'Please enter the URL of your AudiobookShelf Server',
key: const ValueKey('not_connected'),
style: Theme.of(context).textTheme.bodyMedium,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: AddNewServer(
controller: serverUriController,
allowEmpty: true,
onPressed: () {
canUserLogin.value = serverUriController.text.isNotEmpty;
},
),
),
const SizedBox.square(
dimension: 16.0,
),
AnimatedSwitcher(
duration: 500.ms,
transitionBuilder: fadeSlideTransitionBuilder,
child: canUserLogin.value
? UserLoginWidget(
server: audiobookshelfUri,
)
// ).animate().fade(duration: 600.ms).slideY(begin: 0.3, end: 0)
: const RedirectToABS().animate().fadeIn().slideY(
curve: Curves.easeInOut,
duration: 500.ms,
),
),
],
);
}
}

View file

@ -130,11 +130,11 @@ class UserLoginMultipleAuth extends HookConsumerWidget {
return Center(
child: InactiveFocusScopeObserver(
child: AutofillGroup(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Wrap(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
// mainAxisAlignment: MainAxisAlignment.center,
spacing: 10,
runAlignment: WrapAlignment.center,
@ -174,10 +174,10 @@ class UserLoginMultipleAuth extends HookConsumerWidget {
),
],
),
const SizedBox.square(
dimension: 8,
),
switch (methodChoice.value) {
),
Padding(
padding: const EdgeInsets.all(8.0),
child: switch (methodChoice.value) {
AuthMethodChoice.authToken => UserLoginWithToken(
server: server,
addServer: addServer,
@ -192,8 +192,8 @@ class UserLoginMultipleAuth extends HookConsumerWidget {
openIDButtonText: openIDButtonText,
),
},
],
),
),
],
),
),
),

View file

@ -29,6 +29,7 @@ class UserLoginWithPassword extends HookConsumerWidget {
final usernameController = useTextEditingController();
final passwordController = useTextEditingController();
final isPasswordVisibleAnimationController = useAnimationController(
initialValue: 1,
duration: const Duration(milliseconds: 500),
);
@ -92,76 +93,76 @@ class UserLoginWithPassword extends HookConsumerWidget {
return Center(
child: InactiveFocusScopeObserver(
child: AutofillGroup(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: usernameController,
autofocus: true,
autofillHints: const [AutofillHints.username],
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: 'Username',
labelStyle: TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.8),
),
border: const OutlineInputBorder(),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: usernameController,
autofocus: true,
autofillHints: const [AutofillHints.username],
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: 'Username',
labelStyle: TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.8),
),
border: const OutlineInputBorder(),
),
const SizedBox(height: 10),
TextFormField(
controller: passwordController,
autofillHints: const [AutofillHints.password],
textInputAction: TextInputAction.done,
obscureText: !isPasswordVisible.value,
onFieldSubmitted: (_) {
loginAndSave();
},
decoration: InputDecoration(
labelText: 'Password',
labelStyle: TextStyle(
color: Theme.of(context)
),
const SizedBox(height: 10),
TextFormField(
controller: passwordController,
autofillHints: const [AutofillHints.password],
textInputAction: TextInputAction.done,
obscureText: !isPasswordVisible.value,
onFieldSubmitted: (_) {
loginAndSave();
},
decoration: InputDecoration(
labelText: 'Password',
labelStyle: TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.8),
),
border: const OutlineInputBorder(),
suffixIcon: ColorFiltered(
colorFilter: ColorFilter.mode(
Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.8),
.primary
.withValues(alpha: 0.8),
BlendMode.srcIn,
),
border: const OutlineInputBorder(),
suffixIcon: ColorFiltered(
colorFilter: ColorFilter.mode(
Theme.of(context).colorScheme.primary.withOpacity(0.8),
BlendMode.srcIn,
),
child: InkWell(
borderRadius: BorderRadius.circular(50),
onTap: () {
isPasswordVisible.value = !isPasswordVisible.value;
},
child: Container(
margin: const EdgeInsets.only(left: 8, right: 8),
child: Lottie.asset(
'assets/animations/Animation - 1714930099660.json',
controller: isPasswordVisibleAnimationController,
),
child: InkWell(
borderRadius: BorderRadius.circular(50),
onTap: () {
isPasswordVisible.value = !isPasswordVisible.value;
},
child: Container(
margin: const EdgeInsets.only(left: 8, right: 8),
child: Lottie.asset(
'assets/animations/Animation - 1714930099660.json',
controller: isPasswordVisibleAnimationController,
),
),
),
suffixIconConstraints: const BoxConstraints(
maxHeight: 45,
),
),
suffixIconConstraints: const BoxConstraints(
maxHeight: 45,
),
),
const SizedBox(height: 30),
ElevatedButton(
onPressed: loginAndSave,
child: const Text('Login'),
),
],
),
),
const SizedBox(height: 30),
ElevatedButton(
onPressed: loginAndSave,
child: const Text('Login'),
),
],
),
),
),

View file

@ -84,7 +84,10 @@ class UserLoginWithToken extends HookConsumerWidget {
decoration: InputDecoration(
labelText: 'API Token',
labelStyle: TextStyle(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.8),
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.8),
),
border: const OutlineInputBorder(),
),

View file

@ -104,8 +104,10 @@ class PlayerWhenExpanded extends HookConsumerWidget {
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color:
Theme.of(context).colorScheme.primary.withOpacity(0.1),
color: Theme.of(context)
.colorScheme
.primary
.withValues(alpha: 0.1),
blurRadius: 32 * earlyPercentage,
spreadRadius: 8 * earlyPercentage,
// offset: Offset(0, 16 * earlyPercentage),
@ -171,7 +173,7 @@ class PlayerWhenExpanded extends HookConsumerWidget {
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.7),
.withValues(alpha: 0.7),
),
maxLines: 1,
overflow: TextOverflow.ellipsis,

View file

@ -93,7 +93,7 @@ class PlayerWhenMinimized extends HookConsumerWidget {
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.7),
.withValues(alpha: 0.7),
),
),
],

View file

@ -6,7 +6,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:list_wheel_scroll_view_nls/list_wheel_scroll_view_nls.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart';
import 'package:vaani/settings/app_settings_provider.dart';
import 'package:vaani/shared/hooks.dart';
const double itemExtent = 25;

View file

@ -11,7 +11,6 @@ import 'package:vaani/features/sleep_timer/providers/sleep_timer_provider.dart'
import 'package:vaani/main.dart';
import 'package:vaani/settings/app_settings_provider.dart';
import 'package:vaani/shared/extensions/duration_format.dart';
import 'package:vaani/shared/hooks.dart';
class SleepTimerButton extends HookConsumerWidget {
const SleepTimerButton({

View file

@ -261,9 +261,7 @@ class ServerManagerPage extends HookConsumerWidget {
},
),
),
MiniPlayerBottomPadding(),
],
),
),

View file

@ -76,7 +76,7 @@ class HomePage extends HookConsumerWidget {
child: ListView.separated(
itemBuilder: (context, index) => shelvesToDisplay[index],
separatorBuilder: (context, index) => Divider(
color: Theme.of(context).dividerColor.withOpacity(0.1),
color: Theme.of(context).dividerColor.withValues(alpha: 0.1),
indent: 16,
endIndent: 16,
),

View file

@ -61,7 +61,7 @@ class LibraryPage extends HookConsumerWidget {
child: ListView.separated(
itemBuilder: (context, index) => shelvesToDisplay[index],
separatorBuilder: (context, index) => Divider(
color: Theme.of(context).dividerColor.withOpacity(0.1),
color: Theme.of(context).dividerColor.withValues(alpha: 0.1),
indent: 16,
endIndent: 16,
),

View file

@ -16,5 +16,4 @@ class LibraryItemExtras with _$LibraryItemExtras {
BookMinified? book,
@Default('') String heroTagSuffix,
}) = _LibraryItemExtras;
}

View file

@ -1,6 +1,5 @@
import 'package:flutter/foundation.dart' show immutable;
@immutable
class AppMetadata {
const AppMetadata._();

View file

@ -40,7 +40,7 @@ class NavigationWithSwitchTile extends AbstractSettingsTile {
child: Row(
children: [
VerticalDivider(
color: Theme.of(context).dividerColor.withOpacity(0.5),
color: Theme.of(context).dividerColor.withValues(alpha: 0.5),
indent: 8.0,
endIndent: 8.0,
),

View file

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

View file

@ -68,7 +68,7 @@ class AddNewServer extends HookConsumerWidget {
decoration: InputDecoration(
labelText: 'Server URI',
labelStyle: TextStyle(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.8),
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.8),
),
border: const OutlineInputBorder(),
prefixText:

View file

@ -3,7 +3,6 @@ import 'package:go_router/go_router.dart';
import 'package:vaani/features/you/view/server_manager.dart';
import 'package:vaani/router/router.dart';
class MyDrawer extends StatelessWidget {
const MyDrawer({
super.key,

View file

@ -39,7 +39,7 @@ class ExpandableDescription extends HookWidget {
// header with carrot icon is tapable
InkWell(
borderRadius: BorderRadius.circular(8),
onTap: () {
isDescExpanded.value = !isDescExpanded.value;
if (isDescExpanded.value) {

View file

@ -255,8 +255,10 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
child: CircularProgressIndicator(
value: userProgress.progress,
strokeWidth: strokeWidth,
backgroundColor:
Theme.of(context).colorScheme.onPrimary.withOpacity(0.8),
backgroundColor: Theme.of(context)
.colorScheme
.onPrimary
.withValues(alpha: 0.8),
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).colorScheme.primary,
),
@ -274,7 +276,10 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
const Size(size, size),
),
backgroundColor: WidgetStateProperty.all(
Theme.of(context).colorScheme.onPrimary.withOpacity(0.9),
Theme.of(context)
.colorScheme
.onPrimary
.withValues(alpha: 0.9),
),
),
onPressed: () async {
@ -316,9 +321,10 @@ class BookCoverSkeleton extends StatelessWidget {
child: SizedBox(
width: 150,
child: Shimmer.fromColors(
baseColor: Theme.of(context).colorScheme.surface.withOpacity(0.3),
baseColor:
Theme.of(context).colorScheme.surface.withValues(alpha: 0.3),
highlightColor:
Theme.of(context).colorScheme.onSurface.withOpacity(0.1),
Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.1),
child: Container(
color: Theme.of(context).colorScheme.surface,
),

View file

@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 0.0.16+7
version: 0.0.17+8
environment:
sdk: ">=3.3.4 <4.0.0"

@ -1 +1 @@
Subproject commit ac8e94df7b28c4334165a11c3b445cd0cc497495
Subproject commit 5cc545ca87c05615473ab9c363cfa29e341d1e2a