Compare commits

...

8 Commits

Author SHA1 Message Date
Richard Hajek
8e6c91193d
Merge 42e954428b into bbe3394e9e 2025-03-12 15:16:33 +06:00
Kingkor Roy Tirtho
bbe3394e9e fix: lastfm form broken in other locales #2447 2025-03-12 15:05:32 +06:00
Kingkor Roy Tirtho
7cde803bee feat(local_library): add support for x-flac, opus and x-wav 2025-03-12 14:20:19 +06:00
Kingkor Roy Tirtho
cd475e93d0 chore: upgrade action flutter to 3.29.1 2025-03-12 13:48:07 +06:00
Richard Hajek
42e954428b feat: added filtering duplicates in recent 2025-01-18 18:01:26 +01:00
Kingkor Roy Tirtho
8c1337d1fc
Merge pull request #2118 from KRTirtho/dev
chore: release 3.9.0
2024-12-09 00:04:29 +06:00
Kingkor Roy Tirtho
94e704087f Merge branch 'dev' 2024-10-09 16:38:23 +06:00
Kingkor Roy Tirtho
8e287ab1e5
Merge pull request #1981 from KRTirtho/dev
Release 3.8.3
2024-10-09 15:39:31 +06:00
7 changed files with 35 additions and 22 deletions

View File

@ -4,7 +4,7 @@ on:
pull_request: pull_request:
env: env:
FLUTTER_VERSION: 3.29.0 FLUTTER_VERSION: 3.29.1
jobs: jobs:
lint: lint:

View File

@ -20,7 +20,7 @@ on:
description: Dry run without uploading to release description: Dry run without uploading to release
env: env:
FLUTTER_VERSION: 3.29.0 FLUTTER_VERSION: 3.29.1
FLUTTER_CHANNEL: master FLUTTER_CHANNEL: master
permissions: permissions:

View File

@ -9,7 +9,7 @@ import 'package:spotube/provider/history/recent.dart';
class HomeRecentlyPlayedSection extends HookConsumerWidget { class HomeRecentlyPlayedSection extends HookConsumerWidget {
const HomeRecentlyPlayedSection({super.key}); const HomeRecentlyPlayedSection({super.key});
@override @override
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final history = ref.watch(recentlyPlayedItems); final history = ref.watch(recentlyPlayedItems);
@ -20,17 +20,20 @@ class HomeRecentlyPlayedSection extends HookConsumerWidget {
return const SizedBox(); return const SizedBox();
} }
final uniqueItems = <dynamic>{};
final filteredItems = [
for (final item in historyData)
if (item.playlist != null && item.playlist?.id != null && uniqueItems.add(item.playlist!.id!))
item.playlist
else if (item.album != null && item.album?.id != null && uniqueItems.add(item.album?.id))
item.album
];
return Skeletonizer( return Skeletonizer(
enabled: history.isLoading, enabled: history.isLoading,
child: HorizontalPlaybuttonCardView( child: HorizontalPlaybuttonCardView(
title: Text(context.l10n.recently_played), title: Text(context.l10n.recently_played),
items: [ items: filteredItems,
for (final item in historyData)
if (item.playlist != null)
item.playlist
else if (item.album != null)
item.album
],
hasNextPage: false, hasNextPage: false,
isLoadingNextPage: false, isLoadingNextPage: false,
onFetchMore: () {}, onFetchMore: () {},

View File

@ -96,7 +96,9 @@ class LastFMLoginPage extends HookConsumerWidget {
FormField( FormField(
label: Text(context.l10n.username), label: Text(context.l10n.username),
key: usernameKey, key: usernameKey,
validator: const NotEmptyValidator(), validator: const NotEmptyValidator(
message: "Username is required",
),
child: TextField( child: TextField(
autofillHints: const [ autofillHints: const [
AutofillHints.username, AutofillHints.username,
@ -107,7 +109,9 @@ class LastFMLoginPage extends HookConsumerWidget {
), ),
FormField( FormField(
key: passwordKey, key: passwordKey,
validator: const NotEmptyValidator(), validator: const NotEmptyValidator(
message: "Password is required",
),
label: Text(context.l10n.password), label: Text(context.l10n.password),
child: TextField( child: TextField(
autofillHints: const [ autofillHints: const [

View File

@ -24,6 +24,9 @@ const supportedAudioTypes = [
"audio/opus", "audio/opus",
"audio/wav", "audio/wav",
"audio/aac", "audio/aac",
"audio/flac",
"audio/x-flac",
"audio/x-wav",
]; ];
const imgMimeToExt = { const imgMimeToExt = {
@ -68,13 +71,16 @@ final localTracksProvider =
await Directory(location).list(recursive: true).toList(); await Directory(location).list(recursive: true).toList();
entities.addAll( entities.addAll(
dirEntities dirEntities.where(
.where( (e) {
(e) => final mime = lookupMimeType(e.path) ??
e is File && (extension(e.path) == ".opus" ? "audio/opus" : null);
supportedAudioTypes.contains(lookupMimeType(e.path)),
) print("${basename(e.path)}: $mime");
.cast<File>(),
return e is File && supportedAudioTypes.contains(mime);
},
).cast<File>(),
); );
} catch (e, stack) { } catch (e, stack) {
AppLogger.reportError(e, stack); AppLogger.reportError(e, stack);

View File

@ -1539,10 +1539,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: mime name: mime
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.6" version: "2.0.0"
nm: nm:
dependency: transitive dependency: transitive
description: description:

View File

@ -88,7 +88,7 @@ dependencies:
media_kit: ^1.1.10+1 media_kit: ^1.1.10+1
media_kit_libs_audio: ^1.0.4 media_kit_libs_audio: ^1.0.4
metadata_god: ^1.0.0 metadata_god: ^1.0.0
mime: ^1.0.2 mime: ^2.0.0
open_file: ^3.5.10 open_file: ^3.5.10
package_info_plus: ^6.0.0 package_info_plus: ^6.0.0
palette_generator: ^0.3.3 palette_generator: ^0.3.3