Compare commits

..

3 Commits

Author SHA1 Message Date
Guanciottaman
e27f58666e
Merge ff252d6b14 into 151a440e7e 2025-09-09 09:37:06 +06:00
Kingkor Roy Tirtho
151a440e7e chore: bump version to v5 and generate changelogs 2025-09-09 00:51:09 +06:00
Kingkor Roy Tirtho
9471e008e3 fix(ui): lyrics white text in white background and small player buttons 2025-09-09 00:45:45 +06:00
8 changed files with 111 additions and 58 deletions

View File

@ -1,5 +1,68 @@
# Changelog
## [5.0.0](https://github.com/KRTirtho/spotube/compare/v4.0.2...v5.0.0) (2025-09-08)
### Features
- Add ISRC track search for YouTube ([#2594](https://github.com/KRTirtho/spotube/issues/2594))
- Add new icons #2676 by @alexio-dev ([#2678](https://github.com/KRTirtho/spotube/issues/2678))
- Add connect confirmation dialog
- Add metadata api service and models
- **metadata-plugin**: Add pagination support, feed and playlist CRUD endpoints
- **metadata-plugin**: Add local storage api
- Add webview, totp and setInterval apis for plugins
- Enhance local storage and webview APIs with improved error handling and resource management
- **metadata_plugin**: Add logout method
- Update plugin configuration with more fields
- Implement metadata plugins based on hetu
- Update models to match hetu_spotube_plugin signature
- Add user endpoint calls in metadata and paginated async notifiers
- Add playlist endpoint and providers
- Add albums metadata endpoint and provider
- Add artist and album providers
- Add track endpoint for metadata service
- Remove green corp names formally
- **metadata**: Add plugin form
- Add support for entity specific search
- Enhance image handling
- Add support for automatic plugin repository from github and codeberg
- Use isolate for youtube_explode engine
- Add repository and plugin API version fields to metadata plugins
- Update new pipe version
- **metadata**: Add plugin update checker and dialog for available updates
- Optimize track options and related artists
- Add plugin scrobbling support and support button
- Add ErrorBox and NoDefaultMetadataPlugin components
### Bug Fixes
- Calling /track/:streamId endpoint causes active sourced track to be anything
- **mobile**: Dialogs in bottom sheet are not opening
- Default accent color is orange but it shows blue in settings
- Artist images are not loading up
- CVE: Remote path traversal through websocket when devices are on same network
- Endless playback not working
- **android**: NewPipe invalid search content filters
- Make YoutubeExplode engine faster
- Create and delete playlist not working
- Local track not working and images of local not showing up
- Local playback not working for tracks with special # (hashtag) characters
- Inaccessible streaming url causing rapid skips
- **yt**: Fallback to different search result if all streaming url is inaccessible
- **playback**: Skip network requests if cached file already exists
- Yt-dlp playback not working and add partial support for HLS streaming
- Windows webview2 environment permission issue
- **playback**: Play not fetching full playlist if playlist is too long
- **track_options**: Tapping on option doesn't close the menu
- **playback**: Alternative track sources switch not working
- **ui**: Lyrics white text in white background and small player buttons
### Translation
- Add Traditional Chinese translation ([#2762](https://github.com/KRTirtho/spotube/issues/2762))
- Fix Japanese translations ([#2732](https://github.com/KRTirtho/spotube/issues/2732))
- Correction of the dutch language ([#1306](https://github.com/KRTirtho/spotube/issues/1306))
## [4.0.2](https://github.com/krtirtho/spotube/compare/v4.0.1...v4.0.2) (2025-03-16)
### Bug Fixes

View File

@ -13,7 +13,7 @@ class BackButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IconButton.ghost(
size: const ButtonSize(.9),
size: const ButtonSize(1.2),
icon: Icon(icon, color: color),
onPressed: () => Navigator.of(context).pop(),
);

View File

@ -21,7 +21,6 @@ import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/modules/root/spotube_navigation_bar.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/metadata_plugin/core/auth.dart';
import 'package:spotube/provider/server/active_track_sources.dart';
import 'package:spotube/provider/volume_provider.dart';
import 'package:spotube/services/sourced_track/sources/youtube.dart';
@ -40,7 +39,6 @@ class PlayerView extends HookConsumerWidget {
@override
Widget build(BuildContext context, ref) {
final theme = Theme.of(context);
final authenticated = ref.watch(metadataPluginAuthenticatedProvider);
final sourcedCurrentTrack = ref.watch(activeTrackSourcesProvider);
final currentActiveTrack =
ref.watch(audioPlayerProvider.select((s) => s.activeTrack));
@ -105,13 +103,15 @@ class PlayerView extends HookConsumerWidget {
surfaceBlur: 0,
leading: [
IconButton.ghost(
icon: const Icon(SpotubeIcons.angleDown, size: 18),
size: const ButtonSize(1.2),
icon: const Icon(SpotubeIcons.angleDown),
onPressed: panelController.close,
)
],
trailing: [
if (currentActiveTrackSource is YoutubeSourcedTrack)
TextButton(
size: const ButtonSize(1.2),
leading: Assets.images.logos.songlinkTransparent.image(
width: 20,
height: 20,
@ -131,7 +131,8 @@ class PlayerView extends HookConsumerWidget {
child: Text(context.l10n.details),
).call,
child: IconButton.ghost(
icon: const Icon(SpotubeIcons.info, size: 18),
size: const ButtonSize(1.2),
icon: const Icon(SpotubeIcons.info),
onPressed: currentActiveTrackSource == null
? null
: () {
@ -239,9 +240,7 @@ class PlayerView extends HookConsumerWidget {
},
),
),
if (authenticated.asData?.value == true)
const SizedBox(width: 10),
if (authenticated.asData?.value == true)
Expanded(
child: OutlineButton(
leading: const Icon(SpotubeIcons.music),

View File

@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:media_kit/media_kit.dart';
import 'package:palette_generator/palette_generator.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart' hide Consumer;
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/collections/intents.dart';
@ -14,6 +14,7 @@ import 'package:spotube/modules/player/use_progress.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/utils/platform.dart';
class PlayerControls extends HookConsumerWidget {
final PaletteGenerator? palette;
@ -48,6 +49,9 @@ class PlayerControls extends HookConsumerWidget {
useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying;
final theme = Theme.of(context);
final buttonSize =
kIsMobile ? const ButtonSize(1.5) : const ButtonSize(1.2);
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
@ -149,9 +153,11 @@ class PlayerControls extends HookConsumerWidget {
),
).call,
child: IconButton(
size: buttonSize,
icon: Icon(
SpotubeIcons.shuffle,
color: shuffled ? theme.colorScheme.primary : null,
size: 22,
),
variance: shuffled
? ButtonVariance.secondary
@ -170,8 +176,10 @@ class PlayerControls extends HookConsumerWidget {
}),
Tooltip(
tooltip: TooltipContainer(
child: Text(context.l10n.previous_track)).call,
child: Text(context.l10n.previous_track),
).call,
child: IconButton.ghost(
size: buttonSize,
enabled: !isFetchingActiveTrack,
icon: const Icon(SpotubeIcons.skipBack),
onPressed: audioPlayer.skipToPrevious,
@ -186,6 +194,7 @@ class PlayerControls extends HookConsumerWidget {
),
).call,
child: IconButton.primary(
size: buttonSize,
shape: ButtonShape.circle,
icon: isFetchingActiveTrack
? const SizedBox(
@ -206,8 +215,10 @@ class PlayerControls extends HookConsumerWidget {
),
Tooltip(
tooltip:
TooltipContainer(child: Text(context.l10n.next_track)).call,
TooltipContainer(child: Text(context.l10n.next_track))
.call,
child: IconButton.ghost(
size: buttonSize,
icon: const Icon(SpotubeIcons.skipForward),
onPressed:
isFetchingActiveTrack ? null : audioPlayer.skipToNext,
@ -228,6 +239,7 @@ class PlayerControls extends HookConsumerWidget {
),
).call,
child: IconButton(
size: buttonSize,
icon: Icon(
loopMode == PlaylistMode.single
? SpotubeIcons.repeatOne

View File

@ -47,10 +47,8 @@ class PlayerTrackDetails extends HookConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 4),
LinkText(
Text(
playback.activeTrack?.name ?? "",
TrackRoute(trackId: playback.activeTrack?.id ?? ""),
push: true,
overflow: TextOverflow.ellipsis,
style: theme.typography.normal.copyWith(
color: color,

View File

@ -18,8 +18,6 @@ import 'package:spotube/provider/lyrics/synced.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/services/logger/logger.dart';
import 'package:stroke_text/stroke_text.dart';
class SyncedLyrics extends HookConsumerWidget {
final PaletteColor palette;
final bool? isModal;
@ -160,6 +158,9 @@ class SyncedLyrics extends HookConsumerWidget {
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 250),
style: TextStyle(
color: isActive
? theme.colorScheme.foreground
: theme.colorScheme.mutedForeground,
fontWeight: isActive
? FontWeight.w500
: FontWeight.normal,
@ -181,25 +182,7 @@ class SyncedLyrics extends HookConsumerWidget {
}
audioPlayer.seek(time);
},
child: Builder(builder: (context) {
return StrokeText(
text: lyricSlice.text,
textStyle:
DefaultTextStyle.of(context).style,
textColor: switch ((
isActive,
isModal == true
)) {
(true, _) => Colors.white,
(_, true) =>
theme.colorScheme.mutedForeground,
(_, _) => palette.bodyTextColor,
},
strokeColor: isActive
? Colors.black
: Colors.transparent,
);
}),
child: Text(lyricSlice.text),
),
),
),

View File

@ -28,9 +28,7 @@ class PlayerLyricsPage extends HookConsumerWidget {
final selectedIndex = useState(0);
final palette = usePaletteColor(albumArt, ref);
final tabbar = Padding(
padding: const EdgeInsets.all(10),
child: TabList(
final tabbar = TabList(
index: selectedIndex.value,
onChanged: (index) => selectedIndex.value = index,
children: [
@ -41,7 +39,7 @@ class PlayerLyricsPage extends HookConsumerWidget {
child: Text(context.l10n.plain),
),
],
));
);
return Scaffold(
headers: [

View File

@ -3,7 +3,7 @@ description: Open source extensible music streaming platform and app, based on B
publish_to: "none"
version: 4.0.2+41
version: 5.0.0+42
homepage: https://spotube.krtirtho.dev
repository: https://github.com/KRTirtho/spotube