mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-12-11 09:27:30 +00:00
Merge branch 'dev' into feat/spotify-friends
This commit is contained in:
commit
74c47b38ec
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@ -6,6 +6,12 @@
|
|||||||
"type": "dart",
|
"type": "dart",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "lib/main.dart",
|
"program": "lib/main.dart",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "spotube (mobile)",
|
||||||
|
"type": "dart",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "lib/main.dart",
|
||||||
"args": [
|
"args": [
|
||||||
"--flavor",
|
"--flavor",
|
||||||
"dev"
|
"dev"
|
||||||
|
|||||||
12
README.md
12
README.md
@ -2,10 +2,10 @@
|
|||||||
<img width="600" src="assets/spotube_banner.png" alt="Spotube Logo">
|
<img width="600" src="assets/spotube_banner.png" alt="Spotube Logo">
|
||||||
|
|
||||||
An open source, cross-platform Spotify client compatible across multiple platforms<br />
|
An open source, cross-platform Spotify client compatible across multiple platforms<br />
|
||||||
utilizing Spotify's data API and YouTube (or Piped.video or JioSaavn) as an audio source,<br />
|
utilizing Spotify's data API and YouTube, Piped.video or JioSaavn as an audio source,<br />
|
||||||
eliminating the need for Spotify Premium
|
eliminating the need for Spotify Premium
|
||||||
|
|
||||||
Btw it's not another Electron app😉
|
Btw it's not just another Electron app 😉
|
||||||
|
|
||||||
<a href="https://spotube.netlify.app"><img alt="Visit the website" height="56" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/documentation/website_vector.svg"></a>
|
<a href="https://spotube.netlify.app"><img alt="Visit the website" height="56" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/documentation/website_vector.svg"></a>
|
||||||
<a href="https://discord.gg/uJ94vxB6vg"><img alt="Discord Server" height="56" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/social/discord-plural_vector.svg"></a>
|
<a href="https://discord.gg/uJ94vxB6vg"><img alt="Discord Server" height="56" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/social/discord-plural_vector.svg"></a>
|
||||||
@ -26,7 +26,7 @@ Btw it's not another Electron app😉
|
|||||||
## 🌃 Features
|
## 🌃 Features
|
||||||
|
|
||||||
- 🚫 No ads, thanks to the use of public & free Spotify and YT Music APIs¹
|
- 🚫 No ads, thanks to the use of public & free Spotify and YT Music APIs¹
|
||||||
- ⬇️ Downloadable tracks
|
- ⬇️ Freely downloadable tracks
|
||||||
- 🖥️ 📱 Cross-platform support
|
- 🖥️ 📱 Cross-platform support
|
||||||
- 🪶 Small size & less data usage
|
- 🪶 Small size & less data usage
|
||||||
- 🕵️ Anonymous/guest login
|
- 🕵️ Anonymous/guest login
|
||||||
@ -40,13 +40,13 @@ Btw it's not another Electron app😉
|
|||||||
|
|
||||||
### ❌ Unsupported features
|
### ❌ Unsupported features
|
||||||
|
|
||||||
- 🗣️ **Spotify Shows & Podcasts:** Shows and Podcasts can <ins>**never be supported**</ins> because the audio tracks are _only_ available on Spotify and accessing them would require Spotify Premium.
|
- 🗣️ **Spotify Shows & Podcasts:** Shows and Podcasts will <ins>**never be supported**</ins> because the audio tracks are <ins>_only_</ins> available on Spotify and accessing them would require Spotify Premium.
|
||||||
- 🎧 **Spotify Listen Along:** [Coming soon!](https://github.com/KRTirtho/spotube/issues/8)
|
- 🎧 **Spotify Listen Along:** [Coming soon!](https://github.com/KRTirtho/spotube/issues/8)
|
||||||
|
|
||||||
## 📜 ⬇️ Installation guide
|
## 📜 ⬇️ Installation guide
|
||||||
|
|
||||||
New releases usually appear after 3-4 months.<br />
|
New versions usually release every 3-4 months.<br />
|
||||||
This handy table lists all methods you can use to install Spotube:
|
This handy table lists all the methods you can use to install Spotube:
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
BIN
assets/jiosaavn.png
Normal file
BIN
assets/jiosaavn.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/liked-tracks.jpg
Normal file
BIN
assets/liked-tracks.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@ -34,6 +34,9 @@ class Assets {
|
|||||||
AssetGenImage('assets/bengali-patterns-bg.jpg');
|
AssetGenImage('assets/bengali-patterns-bg.jpg');
|
||||||
static const AssetGenImage branding = AssetGenImage('assets/branding.png');
|
static const AssetGenImage branding = AssetGenImage('assets/branding.png');
|
||||||
static const AssetGenImage emptyBox = AssetGenImage('assets/empty_box.png');
|
static const AssetGenImage emptyBox = AssetGenImage('assets/empty_box.png');
|
||||||
|
static const AssetGenImage jiosaavn = AssetGenImage('assets/jiosaavn.png');
|
||||||
|
static const AssetGenImage likedTracks =
|
||||||
|
AssetGenImage('assets/liked-tracks.jpg');
|
||||||
static const AssetGenImage placeholder =
|
static const AssetGenImage placeholder =
|
||||||
AssetGenImage('assets/placeholder.png');
|
AssetGenImage('assets/placeholder.png');
|
||||||
static const AssetGenImage spotubeHeroBanner =
|
static const AssetGenImage spotubeHeroBanner =
|
||||||
@ -74,6 +77,8 @@ class Assets {
|
|||||||
bengaliPatternsBg,
|
bengaliPatternsBg,
|
||||||
branding,
|
branding,
|
||||||
emptyBox,
|
emptyBox,
|
||||||
|
jiosaavn,
|
||||||
|
likedTracks,
|
||||||
placeholder,
|
placeholder,
|
||||||
spotubeHeroBanner,
|
spotubeHeroBanner,
|
||||||
spotubeLogoForeground,
|
spotubeLogoForeground,
|
||||||
|
|||||||
@ -109,4 +109,5 @@ abstract class SpotubeIcons {
|
|||||||
static const normalize = FeatherIcons.barChart2;
|
static const normalize = FeatherIcons.barChart2;
|
||||||
static const wikipedia = SimpleIcons.wikipedia;
|
static const wikipedia = SimpleIcons.wikipedia;
|
||||||
static const discord = SimpleIcons.discord;
|
static const discord = SimpleIcons.discord;
|
||||||
|
static const youtube = SimpleIcons.youtube;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,6 @@ class TokenLoginForm extends HookConsumerWidget {
|
|||||||
final authenticationNotifier =
|
final authenticationNotifier =
|
||||||
ref.watch(AuthenticationNotifier.provider.notifier);
|
ref.watch(AuthenticationNotifier.provider.notifier);
|
||||||
final directCodeController = useTextEditingController();
|
final directCodeController = useTextEditingController();
|
||||||
final keyCodeController = useTextEditingController();
|
|
||||||
final mounted = useIsMounted();
|
final mounted = useIsMounted();
|
||||||
|
|
||||||
final isLoading = useState(false);
|
final isLoading = useState(false);
|
||||||
@ -37,23 +36,13 @@ class TokenLoginForm extends HookConsumerWidget {
|
|||||||
keyboardType: TextInputType.visiblePassword,
|
keyboardType: TextInputType.visiblePassword,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
TextField(
|
|
||||||
controller: keyCodeController,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: context.l10n.spotify_cookie("\"sp_key (or sp_gaid)\""),
|
|
||||||
labelText: context.l10n.cookie_name_cookie("sp_key (or sp_gaid)"),
|
|
||||||
),
|
|
||||||
keyboardType: TextInputType.visiblePassword,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: isLoading.value
|
onPressed: isLoading.value
|
||||||
? null
|
? null
|
||||||
: () async {
|
: () async {
|
||||||
try {
|
try {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
if (keyCodeController.text.isEmpty ||
|
if (directCodeController.text.isEmpty) {
|
||||||
directCodeController.text.isEmpty) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(context.l10n.fill_in_all_fields),
|
content: Text(context.l10n.fill_in_all_fields),
|
||||||
@ -63,7 +52,7 @@ class TokenLoginForm extends HookConsumerWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final cookieHeader =
|
final cookieHeader =
|
||||||
"sp_dc=${directCodeController.text.trim()}; sp_key=${keyCodeController.text.trim()}";
|
"sp_dc=${directCodeController.text.trim()}";
|
||||||
|
|
||||||
authenticationNotifier.setCredentials(
|
authenticationNotifier.setCredentials(
|
||||||
await AuthenticationCredentials.fromCookie(
|
await AuthenticationCredentials.fromCookie(
|
||||||
|
|||||||
@ -21,16 +21,21 @@ class HomeNewReleasesSection extends HookConsumerWidget {
|
|||||||
userArtistsQuery.data?.map((s) => s.id!).toList() ?? const [];
|
userArtistsQuery.data?.map((s) => s.id!).toList() ?? const [];
|
||||||
|
|
||||||
final albums = useMemoized(
|
final albums = useMemoized(
|
||||||
() => newReleases.pages
|
() {
|
||||||
.whereType<Page<AlbumSimple>>()
|
final allReleases = newReleases.pages
|
||||||
.expand((page) => page.items ?? const <AlbumSimple>[])
|
.whereType<Page<AlbumSimple>>()
|
||||||
.where((album) {
|
.expand((page) => page.items ?? const <AlbumSimple>[])
|
||||||
return album.artists
|
.map((album) => TypeConversionUtils.simpleAlbum_X_Album(album));
|
||||||
?.any((artist) => userArtists.contains(artist.id!)) ==
|
|
||||||
true;
|
final userArtistReleases = allReleases.where((album) {
|
||||||
})
|
return album.artists
|
||||||
.map((album) => TypeConversionUtils.simpleAlbum_X_Album(album))
|
?.any((artist) => userArtists.contains(artist.id!)) ==
|
||||||
.toList(),
|
true;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
if (userArtistReleases.isEmpty) return allReleases.toList();
|
||||||
|
return userArtistReleases;
|
||||||
|
},
|
||||||
[newReleases.pages],
|
[newReleases.pages],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -37,21 +37,21 @@ class UserPlaylists extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final likedTracksPlaylist = useMemoized(
|
final likedTracksPlaylist = useMemoized(
|
||||||
() => PlaylistSimple()
|
() => PlaylistSimple()
|
||||||
..name = context.l10n.liked_tracks
|
..name = context.l10n.liked_tracks
|
||||||
..description = context.l10n.liked_tracks_description
|
..description = context.l10n.liked_tracks_description
|
||||||
..type = "playlist"
|
..type = "playlist"
|
||||||
..collaborative = false
|
..collaborative = false
|
||||||
..public = false
|
..public = false
|
||||||
..id = "user-liked-tracks"
|
..id = "user-liked-tracks"
|
||||||
..images = [
|
..images = [
|
||||||
Image()
|
Image()
|
||||||
..height = 300
|
..height = 300
|
||||||
..width = 300
|
..width = 300
|
||||||
..url =
|
..url = "assets/liked-tracks.jpg"
|
||||||
"https://t.scdn.co/images/3099b3803ad9496896c43f22fe9be8c4.png"
|
],
|
||||||
],
|
[context.l10n],
|
||||||
[context.l10n]);
|
);
|
||||||
|
|
||||||
final playlists = useMemoized(
|
final playlists = useMemoized(
|
||||||
() {
|
() {
|
||||||
|
|||||||
@ -5,6 +5,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:spotify/spotify.dart' hide Offset;
|
import 'package:spotify/spotify.dart' hide Offset;
|
||||||
|
import 'package:spotube/collections/assets.gen.dart';
|
||||||
import 'package:spotube/collections/spotube_icons.dart';
|
import 'package:spotube/collections/spotube_icons.dart';
|
||||||
|
|
||||||
import 'package:spotube/components/shared/image/universal_image.dart';
|
import 'package:spotube/components/shared/image/universal_image.dart';
|
||||||
@ -19,10 +20,28 @@ import 'package:spotube/provider/user_preferences/user_preferences_state.dart';
|
|||||||
import 'package:spotube/services/sourced_track/models/source_info.dart';
|
import 'package:spotube/services/sourced_track/models/source_info.dart';
|
||||||
import 'package:spotube/services/sourced_track/models/video_info.dart';
|
import 'package:spotube/services/sourced_track/models/video_info.dart';
|
||||||
import 'package:spotube/services/sourced_track/sourced_track.dart';
|
import 'package:spotube/services/sourced_track/sourced_track.dart';
|
||||||
|
import 'package:spotube/services/sourced_track/sources/jiosaavn.dart';
|
||||||
|
import 'package:spotube/services/sourced_track/sources/piped.dart';
|
||||||
import 'package:spotube/services/sourced_track/sources/youtube.dart';
|
import 'package:spotube/services/sourced_track/sources/youtube.dart';
|
||||||
import 'package:spotube/utils/service_utils.dart';
|
import 'package:spotube/utils/service_utils.dart';
|
||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||||
|
|
||||||
|
final sourceInfoToIconMap = {
|
||||||
|
YoutubeSourceInfo: const Icon(SpotubeIcons.youtube, color: Color(0xFFFF0000)),
|
||||||
|
JioSaavnSourceInfo: Container(
|
||||||
|
height: 30,
|
||||||
|
width: 30,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(90),
|
||||||
|
image: DecorationImage(
|
||||||
|
image: Assets.jiosaavn.provider(),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PipedSourceInfo: const Icon(SpotubeIcons.piped),
|
||||||
|
};
|
||||||
|
|
||||||
class SiblingTracksSheet extends HookConsumerWidget {
|
class SiblingTracksSheet extends HookConsumerWidget {
|
||||||
final bool floating;
|
final bool floating;
|
||||||
const SiblingTracksSheet({
|
const SiblingTracksSheet({
|
||||||
@ -64,17 +83,34 @@ class SiblingTracksSheet extends HookConsumerWidget {
|
|||||||
return <SourceInfo>[];
|
return <SourceInfo>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
final results = await youtubeClient.search.search(searchTerm.trim());
|
final resultsYt = await youtubeClient.search.search(searchTerm.trim());
|
||||||
|
final resultsJioSaavn =
|
||||||
|
await jiosaavnClient.search.songs(searchTerm.trim());
|
||||||
|
|
||||||
return await Future.wait(
|
final searchResults = await Future.wait([
|
||||||
results.map(YoutubeVideoInfo.fromVideo).mapIndexed((i, video) async {
|
...resultsJioSaavn.results.mapIndexed((i, song) async {
|
||||||
|
final siblingType = JioSaavnSourcedTrack.toSiblingType(song);
|
||||||
|
return siblingType.info;
|
||||||
|
}),
|
||||||
|
...resultsYt
|
||||||
|
.map(YoutubeVideoInfo.fromVideo)
|
||||||
|
.mapIndexed((i, video) async {
|
||||||
final siblingType = await YoutubeSourcedTrack.toSiblingType(i, video);
|
final siblingType = await YoutubeSourcedTrack.toSiblingType(i, video);
|
||||||
return siblingType.info;
|
return siblingType.info;
|
||||||
}),
|
}),
|
||||||
);
|
]);
|
||||||
|
final activeSourceInfo =
|
||||||
|
(playlist.activeTrack! as SourcedTrack).sourceInfo;
|
||||||
|
return searchResults
|
||||||
|
..removeWhere((element) => element.id == activeSourceInfo.id)
|
||||||
|
..insert(
|
||||||
|
0,
|
||||||
|
activeSourceInfo,
|
||||||
|
);
|
||||||
}, [
|
}, [
|
||||||
searchTerm,
|
searchTerm,
|
||||||
searchMode.value,
|
searchMode.value,
|
||||||
|
playlist.activeTrack,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
final siblings = useMemoized(
|
final siblings = useMemoized(
|
||||||
@ -104,6 +140,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
|
|||||||
|
|
||||||
final itemBuilder = useCallback(
|
final itemBuilder = useCallback(
|
||||||
(SourceInfo sourceInfo) {
|
(SourceInfo sourceInfo) {
|
||||||
|
final icon = sourceInfoToIconMap[sourceInfo.runtimeType];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(sourceInfo.title),
|
title: Text(sourceInfo.title),
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
@ -118,7 +155,12 @@ class SiblingTracksSheet extends HookConsumerWidget {
|
|||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
),
|
),
|
||||||
trailing: Text(sourceInfo.duration.toHumanReadableString()),
|
trailing: Text(sourceInfo.duration.toHumanReadableString()),
|
||||||
subtitle: Text(sourceInfo.artist),
|
subtitle: Row(
|
||||||
|
children: [
|
||||||
|
if (icon != null) icon,
|
||||||
|
Text(" • ${sourceInfo.artist}"),
|
||||||
|
],
|
||||||
|
),
|
||||||
enabled: playlist.isFetching != true,
|
enabled: playlist.isFetching != true,
|
||||||
selected: playlist.isFetching != true &&
|
selected: playlist.isFetching != true &&
|
||||||
sourceInfo.id ==
|
sourceInfo.id ==
|
||||||
@ -137,7 +179,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
|
|||||||
[playlist.isFetching, playlist.activeTrack, siblings],
|
[playlist.isFetching, playlist.activeTrack, siblings],
|
||||||
);
|
);
|
||||||
|
|
||||||
var mediaQuery = MediaQuery.of(context);
|
final mediaQuery = MediaQuery.of(context);
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: borderRadius,
|
borderRadius: borderRadius,
|
||||||
|
|||||||
@ -159,7 +159,7 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
margin: EdgeInsets.only(
|
margin: EdgeInsets.only(
|
||||||
bottom: 10,
|
bottom: 10,
|
||||||
left: 0,
|
left: 0,
|
||||||
top: kIsMacOS ? 35 : 5,
|
top: kIsMacOS ? 0 : 5,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|||||||
@ -60,10 +60,7 @@ class HorizontalPlaybuttonCardView<T> extends HookWidget {
|
|||||||
onNotification: (notification) => true,
|
onNotification: (notification) => true,
|
||||||
child: ScrollConfiguration(
|
child: ScrollConfiguration(
|
||||||
behavior: ScrollConfiguration.of(context).copyWith(
|
behavior: ScrollConfiguration.of(context).copyWith(
|
||||||
dragDevices: {
|
dragDevices: PointerDeviceKind.values.toSet(),
|
||||||
PointerDeviceKind.touch,
|
|
||||||
PointerDeviceKind.mouse,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
child: items.isEmpty
|
child: items.isEmpty
|
||||||
? ListView.builder(
|
? ListView.builder(
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
|
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@ -62,7 +61,7 @@ class TrackViewFlexHeader extends HookConsumerWidget {
|
|||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: CachedNetworkImageProvider(props.image),
|
image: UniversalImage.imageProvider(props.image),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -25,7 +25,7 @@ void useInitSysTray(WidgetRef ref) {
|
|||||||
}
|
}
|
||||||
final enabled = !playlist.isFetching;
|
final enabled = !playlist.isFetching;
|
||||||
systemTray.value = await DesktopTools.createSystemTrayMenu(
|
systemTray.value = await DesktopTools.createSystemTrayMenu(
|
||||||
title: DesktopTools.platform.isLinux ? "" : "Spotube",
|
title: DesktopTools.platform.isWindows ? "Spotube" : "",
|
||||||
iconPath: "assets/spotube-logo.png",
|
iconPath: "assets/spotube-logo.png",
|
||||||
windowsIconPath: "assets/spotube-logo.ico",
|
windowsIconPath: "assets/spotube-logo.ico",
|
||||||
items: [
|
items: [
|
||||||
|
|||||||
@ -177,11 +177,9 @@
|
|||||||
"step_2": "الخطوة 2",
|
"step_2": "الخطوة 2",
|
||||||
"step_2_steps": "1. بمجرد تسجيل الدخول، اضغط على F12 أو انقر بزر الماوس الأيمن > فحص لفتح أدوات تطوير المتصفح.\n2. ثم انتقل إلى علامة التبويب \"التطبيقات\" (Chrome وEdge وBrave وما إلى ذلك.) أو علامة التبويب \"التخزين\" (Firefox وPalemoon وما إلى ذلك..)\n3. انتقل إلى قسم \"ملفات تعريف الارتباط\" ثم القسم الفرعي \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. بمجرد تسجيل الدخول، اضغط على F12 أو انقر بزر الماوس الأيمن > فحص لفتح أدوات تطوير المتصفح.\n2. ثم انتقل إلى علامة التبويب \"التطبيقات\" (Chrome وEdge وBrave وما إلى ذلك.) أو علامة التبويب \"التخزين\" (Firefox وPalemoon وما إلى ذلك..)\n3. انتقل إلى قسم \"ملفات تعريف الارتباط\" ثم القسم الفرعي \"https://accounts.spotify.com\"",
|
||||||
"step_3": "الخطوة 3",
|
"step_3": "الخطوة 3",
|
||||||
"step_3_steps": "انسخ قيم \"sp_dc\" و \"sp_key\" (أو sp_gaid) الكويز",
|
|
||||||
"success_emoji": "نجاح 🥳",
|
"success_emoji": "نجاح 🥳",
|
||||||
"success_message": "لقد قمت الآن بتسجيل الدخول بنجاح باستخدام حساب Spotify الخاص بك. عمل جيد يا صديقي!",
|
"success_message": "لقد قمت الآن بتسجيل الدخول بنجاح باستخدام حساب Spotify الخاص بك. عمل جيد يا صديقي!",
|
||||||
"step_4": "الخطوة 4",
|
"step_4": "الخطوة 4",
|
||||||
"step_4_steps": "قم بلصق قيم \"sp_dc\" و \"sp_key\" (أو sp_gaid) المنسوخة في الحقول المعنية",
|
|
||||||
"something_went_wrong": "هناك خطأ ما",
|
"something_went_wrong": "هناك خطأ ما",
|
||||||
"piped_instance": "مثيل خادم Piped",
|
"piped_instance": "مثيل خادم Piped",
|
||||||
"piped_description": "مثيل خادم Piped الذي سيتم استخدامه لمطابقة المقطوعة",
|
"piped_description": "مثيل خادم Piped الذي سيتم استخدامه لمطابقة المقطوعة",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "ধাপ 2",
|
"step_2": "ধাপ 2",
|
||||||
"step_2_steps": "১. একবার আপনি লগ ইন করলে, ব্রাউজার ডেভটুল খুলতে F12 বা মাউসের রাইট ক্লিক > \"Inspect to open Browser DevTools\" টিপুন।\n২. তারপর \"Application\" ট্যাবে যান (Chrome, Edge, Brave etc..) অথবা \"Storage\" Tab (Firefox, Palemoon etc..)\n৩. \"Cookies \" বিভাগে যান তারপর \"https://accounts.spotify.com\" উপবিভাগে যান",
|
"step_2_steps": "১. একবার আপনি লগ ইন করলে, ব্রাউজার ডেভটুল খুলতে F12 বা মাউসের রাইট ক্লিক > \"Inspect to open Browser DevTools\" টিপুন।\n২. তারপর \"Application\" ট্যাবে যান (Chrome, Edge, Brave etc..) অথবা \"Storage\" Tab (Firefox, Palemoon etc..)\n৩. \"Cookies \" বিভাগে যান তারপর \"https://accounts.spotify.com\" উপবিভাগে যান",
|
||||||
"step_3": "ধাপ 3",
|
"step_3": "ধাপ 3",
|
||||||
"step_3_steps": "\"sp_dc\" এবং \"sp_key\" (অথবা sp_gaid) কুকিজের মান কপি করুন",
|
|
||||||
"success_emoji": "আমরা সফল🥳",
|
"success_emoji": "আমরা সফল🥳",
|
||||||
"success_message": "এখন আপনি সফলভাবে আপনার Spotify অ্যাকাউন্ট দিয়ে লগ ইন করেছেন। সাধুভাত আপনাকে",
|
"success_message": "এখন আপনি সফলভাবে আপনার Spotify অ্যাকাউন্ট দিয়ে লগ ইন করেছেন। সাধুভাত আপনাকে",
|
||||||
"step_4": "ধাপ 4",
|
"step_4": "ধাপ 4",
|
||||||
"step_4_steps": "কপি করা \"sp_dc\" এবং \"sp_key\" (অথবা sp_gaid) এর মান সংশ্লিষ্ট ফিল্ডে পেস্ট করুন",
|
|
||||||
"something_went_wrong": "কিছু ভুল হয়েছে",
|
"something_went_wrong": "কিছু ভুল হয়েছে",
|
||||||
"piped_instance": "Piped সার্ভার এড্রেস",
|
"piped_instance": "Piped সার্ভার এড্রেস",
|
||||||
"piped_description": "গান ম্যাচ করার জন্য ব্যবহৃত পাইপড সার্ভার",
|
"piped_description": "গান ম্যাচ করার জন্য ব্যবহৃত পাইপড সার্ভার",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "Pas 2",
|
"step_2": "Pas 2",
|
||||||
"step_2_steps": "1. Una vegada que hagi iniciat sessió, premi F12 o faci clic dret amb el ratolí > Inspeccionar per obrir les eines de desenvolulpador del navegador.\n2. Després vagi a la pestanya \"Application\" (Chrome, Edge, Brave, etc.) o \"Storage\" (Firefox, Palemoon, etc.)\n3. Vagi a la secció \"Cookies\" i després a la subsecció \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. Una vegada que hagi iniciat sessió, premi F12 o faci clic dret amb el ratolí > Inspeccionar per obrir les eines de desenvolulpador del navegador.\n2. Després vagi a la pestanya \"Application\" (Chrome, Edge, Brave, etc.) o \"Storage\" (Firefox, Palemoon, etc.)\n3. Vagi a la secció \"Cookies\" i després a la subsecció \"https://accounts.spotify.com\"",
|
||||||
"step_3": "Pas 3",
|
"step_3": "Pas 3",
|
||||||
"step_3_steps": "Copiï els valors de les Cookies \"sp_dc\" i \"sp_key\" (o sp_gaid)",
|
|
||||||
"success_emoji": "Èxit! 🥳",
|
"success_emoji": "Èxit! 🥳",
|
||||||
"success_message": "Ara has iniciat sessió amb èxit al teu compte de Spotify. Bona feina!",
|
"success_message": "Ara has iniciat sessió amb èxit al teu compte de Spotify. Bona feina!",
|
||||||
"step_4": "Pas 4",
|
"step_4": "Pas 4",
|
||||||
"step_4_steps": "Enganxi els valors coppiats de \"sp_dc\" i \"sp_key\" (o sp_gaid) en els camps respectius",
|
|
||||||
"something_went_wrong": "Quelcom ha sortit malament",
|
"something_went_wrong": "Quelcom ha sortit malament",
|
||||||
"piped_instance": "Instància del servidor Piped",
|
"piped_instance": "Instància del servidor Piped",
|
||||||
"piped_description": "La instància del servidor Piped a utilitzar per la coincidència de cançons",
|
"piped_description": "La instància del servidor Piped a utilitzar per la coincidència de cançons",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "Schritt 2",
|
"step_2": "Schritt 2",
|
||||||
"step_2_steps": "1. Wenn du angemeldet bist, drücke F12 oder klicke mit der rechten Maustaste > Inspektion, um die Browser-Entwicklertools zu öffnen.\n2. Gehe dann zum \"Anwendungs\"-Tab (Chrome, Edge, Brave usw.) oder zum \"Storage\"-Tab (Firefox, Palemoon usw.)\n3. Gehe zum Abschnitt \"Cookies\" und dann zum Unterabschnitt \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. Wenn du angemeldet bist, drücke F12 oder klicke mit der rechten Maustaste > Inspektion, um die Browser-Entwicklertools zu öffnen.\n2. Gehe dann zum \"Anwendungs\"-Tab (Chrome, Edge, Brave usw.) oder zum \"Storage\"-Tab (Firefox, Palemoon usw.)\n3. Gehe zum Abschnitt \"Cookies\" und dann zum Unterabschnitt \"https://accounts.spotify.com\"",
|
||||||
"step_3": "Schritt 3",
|
"step_3": "Schritt 3",
|
||||||
"step_3_steps": "Kopiere die Werte der Cookies \"sp_dc\" und \"sp_key\" (oder sp_gaid)",
|
|
||||||
"success_emoji": "Erfolg🥳",
|
"success_emoji": "Erfolg🥳",
|
||||||
"success_message": "Jetzt bist du erfolgreich mit deinem Spotify-Konto angemeldet. Gut gemacht, Kumpel!",
|
"success_message": "Jetzt bist du erfolgreich mit deinem Spotify-Konto angemeldet. Gut gemacht, Kumpel!",
|
||||||
"step_4": "Schritt 4",
|
"step_4": "Schritt 4",
|
||||||
"step_4_steps": "Füge die kopierten Werte von \"sp_dc\" und \"sp_key\" (oder sp_gaid) in die entsprechenden Felder ein",
|
|
||||||
"something_went_wrong": "Etwas ist schiefgelaufen",
|
"something_went_wrong": "Etwas ist schiefgelaufen",
|
||||||
"piped_instance": "Piped-Serverinstanz",
|
"piped_instance": "Piped-Serverinstanz",
|
||||||
"piped_description": "Die Piped-Serverinstanz, die zur Titelzuordnung verwendet werden soll",
|
"piped_description": "Die Piped-Serverinstanz, die zur Titelzuordnung verwendet werden soll",
|
||||||
|
|||||||
@ -177,11 +177,11 @@
|
|||||||
"step_2": "Step 2",
|
"step_2": "Step 2",
|
||||||
"step_2_steps": "1. Once you're logged in, press F12 or Mouse Right Click > Inspect to Open the Browser devtools.\n2. Then go the \"Application\" Tab (Chrome, Edge, Brave etc..) or \"Storage\" Tab (Firefox, Palemoon etc..)\n3. Go to the \"Cookies\" section then the \"https://accounts.spotify.com\" subsection",
|
"step_2_steps": "1. Once you're logged in, press F12 or Mouse Right Click > Inspect to Open the Browser devtools.\n2. Then go the \"Application\" Tab (Chrome, Edge, Brave etc..) or \"Storage\" Tab (Firefox, Palemoon etc..)\n3. Go to the \"Cookies\" section then the \"https://accounts.spotify.com\" subsection",
|
||||||
"step_3": "Step 3",
|
"step_3": "Step 3",
|
||||||
"step_3_steps": "Copy the values of \"sp_dc\" and \"sp_key\" (or sp_gaid) Cookies",
|
"step_3_steps": "Copy the value of \"sp_dc\" Cookie",
|
||||||
"success_emoji": "Success🥳",
|
"success_emoji": "Success🥳",
|
||||||
"success_message": "Now you're successfully Logged In with your Spotify account. Good Job, mate!",
|
"success_message": "Now you've successfully Logged in with your Spotify account. Good Job, mate!",
|
||||||
"step_4": "Step 4",
|
"step_4": "Step 4",
|
||||||
"step_4_steps": "Paste the copied \"sp_dc\" and \"sp_key\" (or sp_gaid) values in the respective fields",
|
"step_4_steps": "Paste the copied \"sp_dc\" value",
|
||||||
"something_went_wrong": "Something went wrong",
|
"something_went_wrong": "Something went wrong",
|
||||||
"piped_instance": "Piped Server Instance",
|
"piped_instance": "Piped Server Instance",
|
||||||
"piped_description": "The Piped server instance to use for track matching",
|
"piped_description": "The Piped server instance to use for track matching",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "Paso 2",
|
"step_2": "Paso 2",
|
||||||
"step_2_steps": "1. Una vez que hayas iniciado sesión, presiona F12 o haz clic derecho con el ratón > Inspeccionar para abrir las herramientas de desarrollo del navegador.\n2. Luego ve a la pestaña \"Application\" (Chrome, Edge, Brave, etc.) o \"Storage\" (Firefox, Palemoon, etc.)\n3. Ve a la sección \"Cookies\" y luego la subsección \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. Una vez que hayas iniciado sesión, presiona F12 o haz clic derecho con el ratón > Inspeccionar para abrir las herramientas de desarrollo del navegador.\n2. Luego ve a la pestaña \"Application\" (Chrome, Edge, Brave, etc.) o \"Storage\" (Firefox, Palemoon, etc.)\n3. Ve a la sección \"Cookies\" y luego la subsección \"https://accounts.spotify.com\"",
|
||||||
"step_3": "Paso 3",
|
"step_3": "Paso 3",
|
||||||
"step_3_steps": "Copia los valores de las Cookies \"sp_dc\" y \"sp_key\" (o sp_gaid)",
|
|
||||||
"success_emoji": "¡Éxito! 🥳",
|
"success_emoji": "¡Éxito! 🥳",
|
||||||
"success_message": "Ahora has iniciado sesión con éxito en tu cuenta de Spotify. ¡Buen trabajo!",
|
"success_message": "Ahora has iniciado sesión con éxito en tu cuenta de Spotify. ¡Buen trabajo!",
|
||||||
"step_4": "Paso 4",
|
"step_4": "Paso 4",
|
||||||
"step_4_steps": "Pega los valores copiados de \"sp_dc\" y \"sp_key\" (o sp_gaid) en los campos respectivos",
|
|
||||||
"something_went_wrong": "Algo salió mal",
|
"something_went_wrong": "Algo salió mal",
|
||||||
"piped_instance": "Instancia del servidor Piped",
|
"piped_instance": "Instancia del servidor Piped",
|
||||||
"piped_description": "La instancia del servidor Piped a utilizar para la coincidencia de pistas",
|
"piped_description": "La instancia del servidor Piped a utilizar para la coincidencia de pistas",
|
||||||
|
|||||||
@ -177,11 +177,9 @@
|
|||||||
"step_2": "گام 2",
|
"step_2": "گام 2",
|
||||||
"step_2_steps": "1. پس از ورود به سیستم، F12 یا کلیک راست ماوس > Inspect را فشار دهید تا ابزارهای توسعه مرورگر باز شود..\n2. سپس به تب \"Application\" (Chrome, Edge, Brave etc..) یا \"Storage\" Tab (Firefox, Palemoon etc..)\n3. به قسمت \"Cookies\" و به پخش \"https://accounts.spotify.com\" بروید",
|
"step_2_steps": "1. پس از ورود به سیستم، F12 یا کلیک راست ماوس > Inspect را فشار دهید تا ابزارهای توسعه مرورگر باز شود..\n2. سپس به تب \"Application\" (Chrome, Edge, Brave etc..) یا \"Storage\" Tab (Firefox, Palemoon etc..)\n3. به قسمت \"Cookies\" و به پخش \"https://accounts.spotify.com\" بروید",
|
||||||
"step_3": "گام 3",
|
"step_3": "گام 3",
|
||||||
"step_3_steps": "کپی کردن مقادیر \"sp_dc\" و \"sp_key\" (یا sp_gaid) کوکی",
|
|
||||||
"success_emoji": "موفقیت🥳",
|
"success_emoji": "موفقیت🥳",
|
||||||
"success_message": "اکنون با موفقیت با حساب اسپوتیفای خود وارد شده اید",
|
"success_message": "اکنون با موفقیت با حساب اسپوتیفای خود وارد شده اید",
|
||||||
"step_4": "مرحله 4",
|
"step_4": "مرحله 4",
|
||||||
"step_4_steps": "مقدار کپی شده را \"sp_dc\" and \"sp_key\" (یا sp_gaid) در فیلد مربوط پر کنید",
|
|
||||||
"something_went_wrong": "اشتباهی رخ داده",
|
"something_went_wrong": "اشتباهی رخ داده",
|
||||||
"piped_instance": "مشکل در ارتباط با سرور",
|
"piped_instance": "مشکل در ارتباط با سرور",
|
||||||
"piped_description": "مشکل در ارتباط با سرور در دریافت آهنگ ها",
|
"piped_description": "مشکل در ارتباط با سرور در دریافت آهنگ ها",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "Étape 2",
|
"step_2": "Étape 2",
|
||||||
"step_2_steps": "1. Une fois connecté, appuyez sur F12 ou clic droit de la souris > Inspecter pour ouvrir les outils de développement du navigateur.\n2. Ensuite, allez dans l'onglet \"Application\" (Chrome, Edge, Brave, etc.) ou l'onglet \"Stockage\" (Firefox, Palemoon, etc.)\n3. Allez dans la section \"Cookies\", puis dans la sous-section \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. Une fois connecté, appuyez sur F12 ou clic droit de la souris > Inspecter pour ouvrir les outils de développement du navigateur.\n2. Ensuite, allez dans l'onglet \"Application\" (Chrome, Edge, Brave, etc.) ou l'onglet \"Stockage\" (Firefox, Palemoon, etc.)\n3. Allez dans la section \"Cookies\", puis dans la sous-section \"https://accounts.spotify.com\"",
|
||||||
"step_3": "Étape 3",
|
"step_3": "Étape 3",
|
||||||
"step_3_steps": "Copiez les valeurs des cookies \"sp_dc\" et \"sp_key\" (ou sp_gaid)",
|
|
||||||
"success_emoji": "Succès🥳",
|
"success_emoji": "Succès🥳",
|
||||||
"success_message": "Vous êtes maintenant connecté avec succès à votre compte Spotify. Bon travail, mon ami!",
|
"success_message": "Vous êtes maintenant connecté avec succès à votre compte Spotify. Bon travail, mon ami!",
|
||||||
"step_4": "Étape 4",
|
"step_4": "Étape 4",
|
||||||
"step_4_steps": "Collez les valeurs copiées de \"sp_dc\" et \"sp_key\" (ou sp_gaid) dans les champs respectifs",
|
|
||||||
"something_went_wrong": "Quelque chose s'est mal passé",
|
"something_went_wrong": "Quelque chose s'est mal passé",
|
||||||
"piped_instance": "Instance pipée",
|
"piped_instance": "Instance pipée",
|
||||||
"piped_description": "L'instance de serveur Piped à utiliser pour la correspondance des pistes",
|
"piped_description": "L'instance de serveur Piped à utiliser pour la correspondance des pistes",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "2 चरण",
|
"step_2": "2 चरण",
|
||||||
"step_2_steps": "1. जब आप लॉगिन हो जाएँ, तो F12 दबाएं या माउस राइट क्लिक> निरीक्षण करें ताकि ब्राउज़र डेवटूल्स खुलें।\n2. फिर ब्राउज़र के \"एप्लिकेशन\" टैब (Chrome, Edge, Brave आदि) या \"स्टोरेज\" टैब (Firefox, Palemoon आदि) में जाएं\n3. \"कुकीज़\" अनुभाग में जाएं फिर \"https: //accounts.spotify.com\" उप-अनुभाग में जाएं",
|
"step_2_steps": "1. जब आप लॉगिन हो जाएँ, तो F12 दबाएं या माउस राइट क्लिक> निरीक्षण करें ताकि ब्राउज़र डेवटूल्स खुलें।\n2. फिर ब्राउज़र के \"एप्लिकेशन\" टैब (Chrome, Edge, Brave आदि) या \"स्टोरेज\" टैब (Firefox, Palemoon आदि) में जाएं\n3. \"कुकीज़\" अनुभाग में जाएं फिर \"https: //accounts.spotify.com\" उप-अनुभाग में जाएं",
|
||||||
"step_3": "स्टेप 3",
|
"step_3": "स्टेप 3",
|
||||||
"step_3_steps": "\"sp_dc\" और \"sp_key\" (या sp_gaid) कुकीज़ के मान कॉपी करें",
|
|
||||||
"success_emoji": "सफलता🥳",
|
"success_emoji": "सफलता🥳",
|
||||||
"success_message": "अब आप अपने स्पॉटिफाई अकाउंट से सफलतापूर्वक लॉगइन हो गए हैं। अच्छा काम किया!",
|
"success_message": "अब आप अपने स्पॉटिफाई अकाउंट से सफलतापूर्वक लॉगइन हो गए हैं। अच्छा काम किया!",
|
||||||
"step_4": "स्टेप 4",
|
"step_4": "स्टेप 4",
|
||||||
"step_4_steps": "कॉपी की गई \"sp_dc\" और \"sp_key\" (या sp_gaid) मानों को संबंधित फील्ड में पेस्ट करें",
|
|
||||||
"something_went_wrong": "कुछ गलत हो गया",
|
"something_went_wrong": "कुछ गलत हो गया",
|
||||||
"piped_instance": "पाइप्ड सर्वर",
|
"piped_instance": "पाइप्ड सर्वर",
|
||||||
"piped_description": "पाइप किए गए सर्वर",
|
"piped_description": "पाइप किए गए सर्वर",
|
||||||
|
|||||||
@ -177,11 +177,9 @@
|
|||||||
"step_2": "Passo 2",
|
"step_2": "Passo 2",
|
||||||
"step_2_steps": "1. Quando sei acceduto premi F12 o premi il tasto destro del Mouse > Ispeziona per aprire gli strumenti di sviluppo del browser.\n2. Vai quindi nel tab \"Applicazione\" (Chrome, Edge, Brave etc..) o tab \"Archiviazione\" (Firefox, Palemoon etc..)\n3. Vai nella sezione \"Cookies\" quindi nella sezione \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. Quando sei acceduto premi F12 o premi il tasto destro del Mouse > Ispeziona per aprire gli strumenti di sviluppo del browser.\n2. Vai quindi nel tab \"Applicazione\" (Chrome, Edge, Brave etc..) o tab \"Archiviazione\" (Firefox, Palemoon etc..)\n3. Vai nella sezione \"Cookies\" quindi nella sezione \"https://accounts.spotify.com\"",
|
||||||
"step_3": "Passo 3",
|
"step_3": "Passo 3",
|
||||||
"step_3_steps": "Copia il valore dei cookie \"sp_dc\" e \"sp_key\" (o sp_gaid)",
|
|
||||||
"success_emoji": "Successo🥳",
|
"success_emoji": "Successo🥳",
|
||||||
"success_message": "Ora hai correttamente effettuato il login al tuo account Spotify. Bel lavoro, amico!",
|
"success_message": "Ora hai correttamente effettuato il login al tuo account Spotify. Bel lavoro, amico!",
|
||||||
"step_4": "Passo 4",
|
"step_4": "Passo 4",
|
||||||
"step_4_steps": "Incolla i valori copiati di \"sp_dc\" e \"sp_key\" (o sp_gaid) nei campi rispettivi",
|
|
||||||
"something_went_wrong": "Qualcosa è andato storto",
|
"something_went_wrong": "Qualcosa è andato storto",
|
||||||
"piped_instance": "Istanza Server Piped",
|
"piped_instance": "Istanza Server Piped",
|
||||||
"piped_description": "L'istanza server Piped da usare per il match della tracccia",
|
"piped_description": "L'istanza server Piped da usare per il match della tracccia",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "ステップ 2",
|
"step_2": "ステップ 2",
|
||||||
"step_2_steps": "1. ログインしたら、F12を押すか、マウス右クリック > 調査(検証)でブラウザの開発者ツール (devtools) を開きます。\n2. アプリケーション (Application) タブ (Chrome, Edge, Brave など) またはストレージタブ (Firefox, Palemoon など)\n3. Cookies 欄を選択し、https://accounts.spotify.com の枝を選びます",
|
"step_2_steps": "1. ログインしたら、F12を押すか、マウス右クリック > 調査(検証)でブラウザの開発者ツール (devtools) を開きます。\n2. アプリケーション (Application) タブ (Chrome, Edge, Brave など) またはストレージタブ (Firefox, Palemoon など)\n3. Cookies 欄を選択し、https://accounts.spotify.com の枝を選びます",
|
||||||
"step_3": "ステップ 3",
|
"step_3": "ステップ 3",
|
||||||
"step_3_steps": "sp_dc と sp_key (または or sp_gaid) の値 (Value) をコピーします",
|
|
||||||
"success_emoji": "成功🥳",
|
"success_emoji": "成功🥳",
|
||||||
"success_message": "アカウントへのログインに成功しました。よくできました!",
|
"success_message": "アカウントへのログインに成功しました。よくできました!",
|
||||||
"step_4": "ステップ 4",
|
"step_4": "ステップ 4",
|
||||||
"step_4_steps": "コピーした sp_dc と sp_key (または or sp_gaid) の値をそれぞれの入力欄に貼り付けます",
|
|
||||||
"something_went_wrong": "何か誤りがあります",
|
"something_went_wrong": "何か誤りがあります",
|
||||||
"piped_instance": "Piped サーバーのインスタンス",
|
"piped_instance": "Piped サーバーのインスタンス",
|
||||||
"piped_description": "曲の一致に使う Piped サーバーのインスタンス",
|
"piped_description": "曲の一致に使う Piped サーバーのインスタンス",
|
||||||
|
|||||||
@ -177,11 +177,9 @@
|
|||||||
"step_2": "Stap 2",
|
"step_2": "Stap 2",
|
||||||
"step_2_steps": "1. Zodra je bent aangemeld, druk je op F12 of klik je met de rechtermuisknop > Inspect om de Browser devtools te openen.\n2. Ga vervolgens naar het tabblad \"Toepassing\" (Chrome, Edge, Brave enz..) of naar het tabblad \"Opslag\" (Firefox, Palemoon enz..).\n3. Ga naar de sectie \"Cookies\" en vervolgens naar de subsectie \"https://accounts.spotify.com\".",
|
"step_2_steps": "1. Zodra je bent aangemeld, druk je op F12 of klik je met de rechtermuisknop > Inspect om de Browser devtools te openen.\n2. Ga vervolgens naar het tabblad \"Toepassing\" (Chrome, Edge, Brave enz..) of naar het tabblad \"Opslag\" (Firefox, Palemoon enz..).\n3. Ga naar de sectie \"Cookies\" en vervolgens naar de subsectie \"https://accounts.spotify.com\".",
|
||||||
"step_3": "Stap 3",
|
"step_3": "Stap 3",
|
||||||
"step_3_steps": "Kopieer de waarden van \"sp_dc\" en \"sp_key\" (of sp_gaid) Cookies",
|
|
||||||
"success_emoji": "Succes🥳",
|
"success_emoji": "Succes🥳",
|
||||||
"success_message": "Je bent nu succesvol ingelogd met je Spotify account. Goed gedaan, maat!",
|
"success_message": "Je bent nu succesvol ingelogd met je Spotify account. Goed gedaan, maat!",
|
||||||
"step_4": "Stap 4",
|
"step_4": "Stap 4",
|
||||||
"step_4_steps": "Plak de gekopieerde \"sp_dc\" en \"sp_key\" (of sp_gaid) waarden in de respectievelijke velden",
|
|
||||||
"something_went_wrong": "Er ging iets mis",
|
"something_went_wrong": "Er ging iets mis",
|
||||||
"piped_instance": "Piped-serverinstantie",
|
"piped_instance": "Piped-serverinstantie",
|
||||||
"piped_description": "De Piped-serverinstantie die moet worden gebruikt voor het matchen van sporen",
|
"piped_description": "De Piped-serverinstantie die moet worden gebruikt voor het matchen van sporen",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "Krok 2",
|
"step_2": "Krok 2",
|
||||||
"step_2_steps": "1. Jeśli jesteś zalogowany, naciśnij klawisz F12 lub Kliknij prawym przyciskiem myszy > Zbadaj, aby odtworzyć narzędzia developerskie.\n2. Następnie przejdź do zakładki \"Application\" (Chrome, Edge, Brave etc..) lub zakładki \"Storage\" (Firefox, Palemoon etc..)\n3. Przejdź do sekcji \"Cookies\" a następnie do pod-sekcji \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. Jeśli jesteś zalogowany, naciśnij klawisz F12 lub Kliknij prawym przyciskiem myszy > Zbadaj, aby odtworzyć narzędzia developerskie.\n2. Następnie przejdź do zakładki \"Application\" (Chrome, Edge, Brave etc..) lub zakładki \"Storage\" (Firefox, Palemoon etc..)\n3. Przejdź do sekcji \"Cookies\" a następnie do pod-sekcji \"https://accounts.spotify.com\"",
|
||||||
"step_3": "Krok 3",
|
"step_3": "Krok 3",
|
||||||
"step_3_steps": "Skopiuj wartości \"sp_dc\" i \"sp_key\" (lub sp_gaid) Ciasteczek",
|
|
||||||
"success_emoji": "Sukces!🥳",
|
"success_emoji": "Sukces!🥳",
|
||||||
"success_message": "Udało ci się zalogować! Dobra robota, stary!",
|
"success_message": "Udało ci się zalogować! Dobra robota, stary!",
|
||||||
"step_4": "Krok 4",
|
"step_4": "Krok 4",
|
||||||
"step_4_steps": "Wklej wartości \"sp_dc\" i \"sp_key\" (lub sp_gaid) do odpowiednich pul.",
|
|
||||||
"something_went_wrong": "Coś poszło nie tak 🙁",
|
"something_went_wrong": "Coś poszło nie tak 🙁",
|
||||||
"piped_instance": "Instancja serwera Piped",
|
"piped_instance": "Instancja serwera Piped",
|
||||||
"piped_description": "Instancja serwera Piped używana jest do dopasowania utworów.",
|
"piped_description": "Instancja serwera Piped używana jest do dopasowania utworów.",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "Passo 2",
|
"step_2": "Passo 2",
|
||||||
"step_2_steps": "1. Uma vez logado, pressione F12 ou clique com o botão direito do mouse > Inspecionar para abrir as ferramentas de desenvolvimento do navegador.\n2. Em seguida, vá para a guia \"Aplicativo\" (Chrome, Edge, Brave, etc.) ou \"Armazenamento\" (Firefox, Palemoon, etc.)\n3. Acesse a seção \"Cookies\" e depois a subseção \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. Uma vez logado, pressione F12 ou clique com o botão direito do mouse > Inspecionar para abrir as ferramentas de desenvolvimento do navegador.\n2. Em seguida, vá para a guia \"Aplicativo\" (Chrome, Edge, Brave, etc.) ou \"Armazenamento\" (Firefox, Palemoon, etc.)\n3. Acesse a seção \"Cookies\" e depois a subseção \"https://accounts.spotify.com\"",
|
||||||
"step_3": "Passo 3",
|
"step_3": "Passo 3",
|
||||||
"step_3_steps": "Copie os valores dos Cookies \"sp_dc\" e \"sp_key\" (ou sp_gaid)",
|
|
||||||
"success_emoji": "Sucesso🥳",
|
"success_emoji": "Sucesso🥳",
|
||||||
"success_message": "Agora você está logado com sucesso em sua conta do Spotify. Bom trabalho!",
|
"success_message": "Agora você está logado com sucesso em sua conta do Spotify. Bom trabalho!",
|
||||||
"step_4": "Passo 4",
|
"step_4": "Passo 4",
|
||||||
"step_4_steps": "Cole os valores copiados \"sp_dc\" e \"sp_key\" (ou sp_gaid) nos campos correspondentes",
|
|
||||||
"something_went_wrong": "Algo deu errado",
|
"something_went_wrong": "Algo deu errado",
|
||||||
"piped_instance": "Instância do Servidor Piped",
|
"piped_instance": "Instância do Servidor Piped",
|
||||||
"piped_description": "A instância do servidor Piped a ser usada para correspondência de faixas",
|
"piped_description": "A instância do servidor Piped a ser usada para correspondência de faixas",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "Шаг 2",
|
"step_2": "Шаг 2",
|
||||||
"step_2_steps": "1. После входа в систему нажмите F12 или щелкните правой кнопкой мыши > «Проверить», чтобы открыть инструменты разработчика браузера.\n2. Затем перейдите на вкладку \"Application\" (Chrome, Edge, Brave и т.д..) or \"Storage\" (Firefox, Palemoon и т.д..)\n3. Перейдите в раздел \"Cookies\", а затем в подраздел \"https://accounts.spotify.com\"",
|
"step_2_steps": "1. После входа в систему нажмите F12 или щелкните правой кнопкой мыши > «Проверить», чтобы открыть инструменты разработчика браузера.\n2. Затем перейдите на вкладку \"Application\" (Chrome, Edge, Brave и т.д..) or \"Storage\" (Firefox, Palemoon и т.д..)\n3. Перейдите в раздел \"Cookies\", а затем в подраздел \"https://accounts.spotify.com\"",
|
||||||
"step_3": "Шаг 3",
|
"step_3": "Шаг 3",
|
||||||
"step_3_steps": "Скопируйте значения \"sp_dc\" и \"sp_key\" (или sp_gaid) Cookies",
|
|
||||||
"success_emoji": "Успешно 🥳",
|
"success_emoji": "Успешно 🥳",
|
||||||
"success_message": "Теперь вы успешно вошли в свою учетную запись Spotify. Отличная работа, приятель!",
|
"success_message": "Теперь вы успешно вошли в свою учетную запись Spotify. Отличная работа, приятель!",
|
||||||
"step_4": "Шаг 4",
|
"step_4": "Шаг 4",
|
||||||
"step_4_steps": "Вставьте скопированные \"sp_dc\" и \"sp_key\" (или sp_gaid) значения в соответствующие поля",
|
|
||||||
"something_went_wrong": "Что-то пошло не так",
|
"something_went_wrong": "Что-то пошло не так",
|
||||||
"piped_instance": "Экземпляр сервера Piped",
|
"piped_instance": "Экземпляр сервера Piped",
|
||||||
"piped_description": "Серверный экземпляр Piped для сопоставления треков",
|
"piped_description": "Серверный экземпляр Piped для сопоставления треков",
|
||||||
|
|||||||
@ -177,11 +177,9 @@
|
|||||||
"step_2": "2. Adım",
|
"step_2": "2. Adım",
|
||||||
"step_2_steps": "1. Giriş yaptıktan sonra, Tarayıcı devtools.\n2'yi açmak için F12'ye basın veya Fare Sağ Tıklaması > İncele'ye basın. Ardından \"Uygulama\" Sekmesine (Chrome, Edge, Brave vb.) veya \"Depolama\" Sekmesine (Firefox, Palemoon vb.) gidin\n3. \"Çerezler\" bölümüne ve ardından \"https://accounts.spotify.com\" alt bölümüne gidin",
|
"step_2_steps": "1. Giriş yaptıktan sonra, Tarayıcı devtools.\n2'yi açmak için F12'ye basın veya Fare Sağ Tıklaması > İncele'ye basın. Ardından \"Uygulama\" Sekmesine (Chrome, Edge, Brave vb.) veya \"Depolama\" Sekmesine (Firefox, Palemoon vb.) gidin\n3. \"Çerezler\" bölümüne ve ardından \"https://accounts.spotify.com\" alt bölümüne gidin",
|
||||||
"step_3": "3. Adım",
|
"step_3": "3. Adım",
|
||||||
"step_3_steps": "\"sp_dc\" ve \"sp_key\" (veya sp_gaid) Çerezlerinin değerlerini kopyalayın",
|
|
||||||
"success_emoji": "Başarılı🥳",
|
"success_emoji": "Başarılı🥳",
|
||||||
"success_message": "Şimdi Spotify hesabınızla başarılı bir şekilde oturum açtınız. İyi iş, dostum!",
|
"success_message": "Şimdi Spotify hesabınızla başarılı bir şekilde oturum açtınız. İyi iş, dostum!",
|
||||||
"step_4": "4. Adım",
|
"step_4": "4. Adım",
|
||||||
"step_4_steps": "Kopyalanan \"sp_dc\" ve \"sp_key\" (veya sp_gaid) değerlerini ilgili alanlara yapıştırın",
|
|
||||||
"something_went_wrong": "Bir şeyler ters gitti",
|
"something_went_wrong": "Bir şeyler ters gitti",
|
||||||
"piped_instance": "Piped Sunucu Örneği",
|
"piped_instance": "Piped Sunucu Örneği",
|
||||||
"piped_description": "Parça eşleştirme için kullanılacak Piped sunucu örneği",
|
"piped_description": "Parça eşleştirme için kullanılacak Piped sunucu örneği",
|
||||||
|
|||||||
@ -177,11 +177,9 @@
|
|||||||
"step_2": "Крок 2",
|
"step_2": "Крок 2",
|
||||||
"step_2_steps": "1. Після входу натисніть F12 або клацніть правою кнопкою миші > Інспектувати, щоб відкрити інструменти розробки браузера.\n2. Потім перейдіть на вкладку 'Програма' (Chrome, Edge, Brave тощо) або вкладку 'Сховище' (Firefox, Palemoon тощо).\n3. Перейдіть до розділу 'Кукі-файли', а потім до підрозділу 'https://accounts.spotify.com'",
|
"step_2_steps": "1. Після входу натисніть F12 або клацніть правою кнопкою миші > Інспектувати, щоб відкрити інструменти розробки браузера.\n2. Потім перейдіть на вкладку 'Програма' (Chrome, Edge, Brave тощо) або вкладку 'Сховище' (Firefox, Palemoon тощо).\n3. Перейдіть до розділу 'Кукі-файли', а потім до підрозділу 'https://accounts.spotify.com'",
|
||||||
"step_3": "Крок 3",
|
"step_3": "Крок 3",
|
||||||
"step_3_steps": "Скопіюйте значення кукі-файлів 'sp_dc' та 'sp_key' (або sp_gaid)",
|
|
||||||
"success_emoji": "Успіх🥳",
|
"success_emoji": "Успіх🥳",
|
||||||
"success_message": "Тепер ви успішно ввійшли у свій обліковий запис Spotify. Гарна робота, друже!",
|
"success_message": "Тепер ви успішно ввійшли у свій обліковий запис Spotify. Гарна робота, друже!",
|
||||||
"step_4": "Крок 4",
|
"step_4": "Крок 4",
|
||||||
"step_4_steps": "Вставте скопійовані значення 'sp_dc' та 'sp_key' (або sp_gaid) у відповідні поля",
|
|
||||||
"something_went_wrong": "Щось пішло не так",
|
"something_went_wrong": "Щось пішло не так",
|
||||||
"piped_instance": "Примірник сервера Piped",
|
"piped_instance": "Примірник сервера Piped",
|
||||||
"piped_description": "Примірник сервера Piped, який використовуватиметься для зіставлення треків",
|
"piped_description": "Примірник сервера Piped, який використовуватиметься для зіставлення треків",
|
||||||
|
|||||||
@ -175,11 +175,9 @@
|
|||||||
"step_2": "步骤 2",
|
"step_2": "步骤 2",
|
||||||
"step_2_steps": "1. 一旦你已经完成登录, 按 F12 键或者鼠标右击网页空白区域 > 选择“检查”以打开浏览器开发者工具(DevTools)\n2. 然后选择 \"应用(Application)\" 标签页(Chrome, Edge, Brave 等基于 Chromium 的浏览器) 或 \"存储(Storage)\" 标签页 (Firefox, Palemoon 等基于 Firefox 的浏览器))\n3. 选择 \"Cookies\" 栏目然后选择 \"https://accounts.spotify.com\" 子栏目",
|
"step_2_steps": "1. 一旦你已经完成登录, 按 F12 键或者鼠标右击网页空白区域 > 选择“检查”以打开浏览器开发者工具(DevTools)\n2. 然后选择 \"应用(Application)\" 标签页(Chrome, Edge, Brave 等基于 Chromium 的浏览器) 或 \"存储(Storage)\" 标签页 (Firefox, Palemoon 等基于 Firefox 的浏览器))\n3. 选择 \"Cookies\" 栏目然后选择 \"https://accounts.spotify.com\" 子栏目",
|
||||||
"step_3": "步骤 3",
|
"step_3": "步骤 3",
|
||||||
"step_3_steps": "复制名称为 \"sp_dc\" 和 \"sp_key\" (或 sp_gaid) 的值(Cookie Value)",
|
|
||||||
"success_emoji": "成功🥳",
|
"success_emoji": "成功🥳",
|
||||||
"success_message": "你已经成功使用 Spotify 登录。干得漂亮!",
|
"success_message": "你已经成功使用 Spotify 登录。干得漂亮!",
|
||||||
"step_4": "步骤 4",
|
"step_4": "步骤 4",
|
||||||
"step_4_steps": "将 \"sp_dc\" 与 \"sp_key\" (或 sp_gaid) 的值分别复制后粘贴到对应的区域",
|
|
||||||
"something_went_wrong": "某些地方出现了问题",
|
"something_went_wrong": "某些地方出现了问题",
|
||||||
"piped_instance": "管道服务器实例",
|
"piped_instance": "管道服务器实例",
|
||||||
"piped_description": "管道服务器实例用于匹配歌曲",
|
"piped_description": "管道服务器实例用于匹配歌曲",
|
||||||
|
|||||||
@ -55,12 +55,7 @@ class WebViewLogin extends HookConsumerWidget {
|
|||||||
final cookies =
|
final cookies =
|
||||||
await CookieManager.instance().getCookies(url: action);
|
await CookieManager.instance().getCookies(url: action);
|
||||||
final cookieHeader =
|
final cookieHeader =
|
||||||
cookies.fold<String>("", (previousValue, element) {
|
"sp_dc=${cookies.firstWhere((element) => element.name == "sp_dc").value}";
|
||||||
if (element.name == "sp_dc" || element.name == "sp_key") {
|
|
||||||
return "$previousValue; ${element.name}=${element.value}";
|
|
||||||
}
|
|
||||||
return previousValue;
|
|
||||||
});
|
|
||||||
|
|
||||||
authenticationNotifier.setCredentials(
|
authenticationNotifier.setCredentials(
|
||||||
await AuthenticationCredentials.fromCookie(cookieHeader),
|
await AuthenticationCredentials.fromCookie(cookieHeader),
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import 'package:spotify/spotify.dart';
|
|||||||
import 'package:spotube/components/shared/tracks_view/track_view.dart';
|
import 'package:spotube/components/shared/tracks_view/track_view.dart';
|
||||||
import 'package:spotube/components/shared/tracks_view/track_view_props.dart';
|
import 'package:spotube/components/shared/tracks_view/track_view_props.dart';
|
||||||
import 'package:spotube/services/queries/queries.dart';
|
import 'package:spotube/services/queries/queries.dart';
|
||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
|
||||||
|
|
||||||
class LikedPlaylistPage extends HookConsumerWidget {
|
class LikedPlaylistPage extends HookConsumerWidget {
|
||||||
final PlaylistSimple playlist;
|
final PlaylistSimple playlist;
|
||||||
@ -20,10 +19,7 @@ class LikedPlaylistPage extends HookConsumerWidget {
|
|||||||
|
|
||||||
return InheritedTrackView(
|
return InheritedTrackView(
|
||||||
collectionId: playlist.id!,
|
collectionId: playlist.id!,
|
||||||
image: TypeConversionUtils.image_X_UrlString(
|
image: "assets/liked-tracks.jpg",
|
||||||
playlist.images,
|
|
||||||
placeholder: ImagePlaceholder.collection,
|
|
||||||
),
|
|
||||||
pagination: PaginationProps(
|
pagination: PaginationProps(
|
||||||
hasNextPage: false,
|
hasNextPage: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
|||||||
@ -173,7 +173,61 @@ class CustomSpotifyEndpoints {
|
|||||||
"accept": "application/json",
|
"accept": "application/json",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return SpotifyFriends.fromJson(jsonDecode(res.body));
|
return SpotifyFriends.fromJson(jsonDecode(res.body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Artist> artist({required String id}) async {
|
||||||
|
final pathQuery = "$_baseUrl/artists/$id";
|
||||||
|
|
||||||
|
final res = await _client.get(
|
||||||
|
Uri.parse(pathQuery),
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json",
|
||||||
|
if (accessToken.isNotEmpty) "authorization": "Bearer $accessToken",
|
||||||
|
"accept": "application/json",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
final data = jsonDecode(res.body);
|
||||||
|
|
||||||
|
return Artist.fromJson(_purifyArtistResponse(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Artist>> relatedArtists({required String id}) async {
|
||||||
|
final pathQuery = "$_baseUrl/artists/$id/related-artists";
|
||||||
|
|
||||||
|
final res = await _client.get(
|
||||||
|
Uri.parse(pathQuery),
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json",
|
||||||
|
if (accessToken.isNotEmpty) "authorization": "Bearer $accessToken",
|
||||||
|
"accept": "application/json",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final data = jsonDecode(res.body);
|
||||||
|
|
||||||
|
return List.castFrom<dynamic, Artist>(
|
||||||
|
data["artists"]
|
||||||
|
.map((artist) => Artist.fromJson(_purifyArtistResponse(artist)))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _purifyArtistResponse(Map<String, dynamic> data) {
|
||||||
|
if (data["popularity"] != null) {
|
||||||
|
data["popularity"] = data["popularity"].toInt();
|
||||||
|
}
|
||||||
|
if (data["followers"]?["total"] != null) {
|
||||||
|
data["followers"]["total"] = data["followers"]["total"].toInt();
|
||||||
|
}
|
||||||
|
if (data["images"] != null) {
|
||||||
|
data["images"] = data["images"].map((e) {
|
||||||
|
e["height"] = e["height"].toInt();
|
||||||
|
e["width"] = e["width"].toInt();
|
||||||
|
return e;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
import 'package:spotube/hooks/spotify/use_spotify_infinite_query.dart';
|
import 'package:spotube/hooks/spotify/use_spotify_infinite_query.dart';
|
||||||
import 'package:spotube/hooks/spotify/use_spotify_query.dart';
|
import 'package:spotube/hooks/spotify/use_spotify_query.dart';
|
||||||
|
import 'package:spotube/provider/custom_spotify_endpoint_provider.dart';
|
||||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||||
import 'package:spotube/services/wikipedia/wikipedia.dart';
|
import 'package:spotube/services/wikipedia/wikipedia.dart';
|
||||||
import 'package:wikipedia_api/wikipedia_api.dart';
|
import 'package:wikipedia_api/wikipedia_api.dart';
|
||||||
@ -15,9 +16,10 @@ class ArtistQueries {
|
|||||||
WidgetRef ref,
|
WidgetRef ref,
|
||||||
String artist,
|
String artist,
|
||||||
) {
|
) {
|
||||||
|
final customSpotify = ref.watch(customSpotifyEndpointProvider);
|
||||||
return useSpotifyQuery<Artist, dynamic>(
|
return useSpotifyQuery<Artist, dynamic>(
|
||||||
"artist-profile/$artist",
|
"artist-profile/$artist",
|
||||||
(spotify) => spotify.artists.get(artist),
|
(spotify) => customSpotify.artist(id: artist),
|
||||||
ref: ref,
|
ref: ref,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -125,10 +127,11 @@ class ArtistQueries {
|
|||||||
WidgetRef ref,
|
WidgetRef ref,
|
||||||
String artist,
|
String artist,
|
||||||
) {
|
) {
|
||||||
|
final customSpotify = ref.watch(customSpotifyEndpointProvider);
|
||||||
return useSpotifyQuery<Iterable<Artist>, dynamic>(
|
return useSpotifyQuery<Iterable<Artist>, dynamic>(
|
||||||
"artist-related-artist-query/$artist",
|
"artist-related-artist-query/$artist",
|
||||||
(spotify) {
|
(spotify) {
|
||||||
return spotify.artists.relatedArtists(artist);
|
return customSpotify.relatedArtists(id: artist);
|
||||||
},
|
},
|
||||||
ref: ref,
|
ref: ref,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -15,4 +15,4 @@ enum SourceQualities {
|
|||||||
low,
|
low,
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef SiblingType = ({SourceInfo info, SourceMap? source});
|
typedef SiblingType<T extends SourceInfo> = ({T info, SourceMap? source});
|
||||||
|
|||||||
@ -12,6 +12,19 @@ import 'package:spotube/extensions/string.dart';
|
|||||||
|
|
||||||
final jiosaavnClient = JioSaavnClient();
|
final jiosaavnClient = JioSaavnClient();
|
||||||
|
|
||||||
|
class JioSaavnSourceInfo extends SourceInfo {
|
||||||
|
JioSaavnSourceInfo({
|
||||||
|
required super.id,
|
||||||
|
required super.title,
|
||||||
|
required super.artist,
|
||||||
|
required super.thumbnail,
|
||||||
|
required super.pageUrl,
|
||||||
|
required super.duration,
|
||||||
|
required super.artistUrl,
|
||||||
|
required super.album,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class JioSaavnSourcedTrack extends SourcedTrack {
|
class JioSaavnSourcedTrack extends SourcedTrack {
|
||||||
JioSaavnSourcedTrack({
|
JioSaavnSourcedTrack({
|
||||||
required super.ref,
|
required super.ref,
|
||||||
@ -70,7 +83,7 @@ class JioSaavnSourcedTrack extends SourcedTrack {
|
|||||||
|
|
||||||
static SiblingType toSiblingType(SongResponse result) {
|
static SiblingType toSiblingType(SongResponse result) {
|
||||||
final SiblingType sibling = (
|
final SiblingType sibling = (
|
||||||
info: SourceInfo(
|
info: JioSaavnSourceInfo(
|
||||||
artist: [
|
artist: [
|
||||||
result.primaryArtists,
|
result.primaryArtists,
|
||||||
if (result.featuredArtists.isNotEmpty) ", ",
|
if (result.featuredArtists.isNotEmpty) ", ",
|
||||||
@ -155,12 +168,16 @@ class JioSaavnSourcedTrack extends SourcedTrack {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<JioSaavnSourcedTrack?> swapWithSibling(SourceInfo sibling) async {
|
Future<JioSaavnSourcedTrack?> swapWithSibling(SourceInfo sibling) async {
|
||||||
if (sibling.id == sourceInfo.id ||
|
if (sibling.id == sourceInfo.id) {
|
||||||
siblings.none((s) => s.id == sibling.id)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final newSourceInfo = siblings.firstWhere((s) => s.id == sibling.id);
|
// a sibling source that was fetched from the search results
|
||||||
|
final isStepSibling = siblings.none((s) => s.id == sibling.id);
|
||||||
|
|
||||||
|
final newSourceInfo = isStepSibling
|
||||||
|
? sibling
|
||||||
|
: siblings.firstWhere((s) => s.id == sibling.id);
|
||||||
final newSiblings = siblings.where((s) => s.id != sibling.id).toList()
|
final newSiblings = siblings.where((s) => s.id != sibling.id).toList()
|
||||||
..insert(0, sourceInfo);
|
..insert(0, sourceInfo);
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,19 @@ final pipedProvider = Provider<PipedClient>(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
class PipedSourceInfo extends SourceInfo {
|
||||||
|
PipedSourceInfo({
|
||||||
|
required super.id,
|
||||||
|
required super.title,
|
||||||
|
required super.artist,
|
||||||
|
required super.thumbnail,
|
||||||
|
required super.pageUrl,
|
||||||
|
required super.duration,
|
||||||
|
required super.artistUrl,
|
||||||
|
required super.album,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class PipedSourcedTrack extends SourcedTrack {
|
class PipedSourcedTrack extends SourcedTrack {
|
||||||
PipedSourcedTrack({
|
PipedSourcedTrack({
|
||||||
required super.ref,
|
required super.ref,
|
||||||
@ -71,7 +84,7 @@ class PipedSourcedTrack extends SourcedTrack {
|
|||||||
ref: ref,
|
ref: ref,
|
||||||
siblings: [],
|
siblings: [],
|
||||||
source: toSourceMap(manifest),
|
source: toSourceMap(manifest),
|
||||||
sourceInfo: SourceInfo(
|
sourceInfo: PipedSourceInfo(
|
||||||
id: manifest.id,
|
id: manifest.id,
|
||||||
artist: manifest.uploader,
|
artist: manifest.uploader,
|
||||||
artistUrl: manifest.uploaderUrl,
|
artistUrl: manifest.uploaderUrl,
|
||||||
@ -122,7 +135,7 @@ class PipedSourcedTrack extends SourcedTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final SiblingType sibling = (
|
final SiblingType sibling = (
|
||||||
info: SourceInfo(
|
info: PipedSourceInfo(
|
||||||
id: item.id,
|
id: item.id,
|
||||||
artist: item.channelName,
|
artist: item.channelName,
|
||||||
artistUrl: "https://www.youtube.com/${item.channelId}",
|
artistUrl: "https://www.youtube.com/${item.channelId}",
|
||||||
@ -233,12 +246,16 @@ class PipedSourcedTrack extends SourcedTrack {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<SourcedTrack?> swapWithSibling(SourceInfo sibling) async {
|
Future<SourcedTrack?> swapWithSibling(SourceInfo sibling) async {
|
||||||
if (sibling.id == sourceInfo.id ||
|
if (sibling.id == sourceInfo.id) {
|
||||||
siblings.none((s) => s.id == sibling.id)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final newSourceInfo = siblings.firstWhere((s) => s.id == sibling.id);
|
// a sibling source that was fetched from the search results
|
||||||
|
final isStepSibling = siblings.none((s) => s.id == sibling.id);
|
||||||
|
|
||||||
|
final newSourceInfo = isStepSibling
|
||||||
|
? sibling
|
||||||
|
: siblings.firstWhere((s) => s.id == sibling.id);
|
||||||
final newSiblings = siblings.where((s) => s.id != sibling.id).toList()
|
final newSiblings = siblings.where((s) => s.id != sibling.id).toList()
|
||||||
..insert(0, sourceInfo);
|
..insert(0, sourceInfo);
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,19 @@ final officialMusicRegex = RegExp(
|
|||||||
caseSensitive: false,
|
caseSensitive: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
class YoutubeSourceInfo extends SourceInfo {
|
||||||
|
YoutubeSourceInfo({
|
||||||
|
required super.id,
|
||||||
|
required super.title,
|
||||||
|
required super.artist,
|
||||||
|
required super.thumbnail,
|
||||||
|
required super.pageUrl,
|
||||||
|
required super.duration,
|
||||||
|
required super.artistUrl,
|
||||||
|
required super.album,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class YoutubeSourcedTrack extends SourcedTrack {
|
class YoutubeSourcedTrack extends SourcedTrack {
|
||||||
YoutubeSourcedTrack({
|
YoutubeSourcedTrack({
|
||||||
required super.source,
|
required super.source,
|
||||||
@ -64,7 +77,7 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
|||||||
ref: ref,
|
ref: ref,
|
||||||
siblings: [],
|
siblings: [],
|
||||||
source: toSourceMap(manifest),
|
source: toSourceMap(manifest),
|
||||||
sourceInfo: SourceInfo(
|
sourceInfo: YoutubeSourceInfo(
|
||||||
id: item.id.value,
|
id: item.id.value,
|
||||||
artist: item.author,
|
artist: item.author,
|
||||||
artistUrl: "https://www.youtube.com/channel/${item.channelId}",
|
artistUrl: "https://www.youtube.com/channel/${item.channelId}",
|
||||||
@ -117,7 +130,7 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final SiblingType sibling = (
|
final SiblingType sibling = (
|
||||||
info: SourceInfo(
|
info: YoutubeSourceInfo(
|
||||||
id: item.id,
|
id: item.id,
|
||||||
artist: item.channelName,
|
artist: item.channelName,
|
||||||
artistUrl: "https://www.youtube.com/channel/${item.channelId}",
|
artistUrl: "https://www.youtube.com/channel/${item.channelId}",
|
||||||
@ -217,12 +230,16 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<YoutubeSourcedTrack?> swapWithSibling(SourceInfo sibling) async {
|
Future<YoutubeSourcedTrack?> swapWithSibling(SourceInfo sibling) async {
|
||||||
if (sibling.id == sourceInfo.id ||
|
if (sibling.id == sourceInfo.id) {
|
||||||
siblings.none((s) => s.id == sibling.id)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final newSourceInfo = siblings.firstWhere((s) => s.id == sibling.id);
|
// a sibling source that was fetched from the search results
|
||||||
|
final isStepSibling = siblings.none((s) => s.id == sibling.id);
|
||||||
|
|
||||||
|
final newSourceInfo = isStepSibling
|
||||||
|
? sibling
|
||||||
|
: siblings.firstWhere((s) => s.id == sibling.id);
|
||||||
final newSiblings = siblings.where((s) => s.id != sibling.id).toList()
|
final newSiblings = siblings.where((s) => s.id != sibling.id).toList()
|
||||||
..insert(0, sourceInfo);
|
..insert(0, sourceInfo);
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
platform :osx, '10.13'
|
platform :osx, '10.14'
|
||||||
|
|
||||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|||||||
@ -1,101 +1,146 @@
|
|||||||
PODS:
|
PODS:
|
||||||
|
- app_links (1.0.0):
|
||||||
|
- FlutterMacOS
|
||||||
- audio_service (0.14.1):
|
- audio_service (0.14.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- audio_session (0.0.1):
|
- audio_session (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- audioplayers_darwin (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- bitsdojo_window_macos (0.0.1):
|
- file_selector_macos (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- connectivity_plus_macos (0.0.1):
|
- flutter_secure_storage_macos (6.1.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- ReachabilitySwift
|
|
||||||
- FlutterMacOS (1.0.0)
|
- FlutterMacOS (1.0.0)
|
||||||
- FMDB (2.7.5):
|
- FMDB (2.7.5):
|
||||||
- FMDB/standard (= 2.7.5)
|
- FMDB/standard (= 2.7.5)
|
||||||
- FMDB/standard (2.7.5)
|
- FMDB/standard (2.7.5)
|
||||||
- macos_ui (0.1.0):
|
- local_notifier (0.1.0):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- metadata_god (0.0.1):
|
- media_kit_libs_macos_audio (1.0.4):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- package_info_plus_macos (0.0.1):
|
- media_kit_native_event_loop (1.0.0):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- path_provider_macos (0.0.1):
|
- metadata_god (0.0.1)
|
||||||
|
- package_info_plus (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- ReachabilitySwift (5.0.0)
|
- path_provider_foundation (0.0.1):
|
||||||
- shared_preferences_macos (0.0.1):
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- screen_retriever (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
- shared_preferences_foundation (0.0.1):
|
||||||
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- sqflite (0.0.2):
|
- sqflite (0.0.2):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- FMDB (>= 2.7.5)
|
- FMDB (>= 2.7.5)
|
||||||
|
- system_theme (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
- system_tray (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
- url_launcher_macos (0.0.1):
|
- url_launcher_macos (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- window_manager (0.2.0):
|
||||||
|
- FlutterMacOS
|
||||||
|
- window_size (0.0.2):
|
||||||
|
- FlutterMacOS
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
|
- app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`)
|
||||||
- audio_service (from `Flutter/ephemeral/.symlinks/plugins/audio_service/macos`)
|
- audio_service (from `Flutter/ephemeral/.symlinks/plugins/audio_service/macos`)
|
||||||
- audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`)
|
- audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`)
|
||||||
- audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos`)
|
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
|
||||||
- bitsdojo_window_macos (from `Flutter/ephemeral/.symlinks/plugins/bitsdojo_window_macos/macos`)
|
- file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`)
|
||||||
- connectivity_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos`)
|
- flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`)
|
||||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||||
- macos_ui (from `Flutter/ephemeral/.symlinks/plugins/macos_ui/macos`)
|
- local_notifier (from `Flutter/ephemeral/.symlinks/plugins/local_notifier/macos`)
|
||||||
|
- media_kit_libs_macos_audio (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_audio/macos`)
|
||||||
|
- media_kit_native_event_loop (from `Flutter/ephemeral/.symlinks/plugins/media_kit_native_event_loop/macos`)
|
||||||
- metadata_god (from `Flutter/ephemeral/.symlinks/plugins/metadata_god/macos`)
|
- metadata_god (from `Flutter/ephemeral/.symlinks/plugins/metadata_god/macos`)
|
||||||
- package_info_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos`)
|
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
||||||
- path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`)
|
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`)
|
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
|
||||||
|
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`)
|
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`)
|
||||||
|
- system_theme (from `Flutter/ephemeral/.symlinks/plugins/system_theme/macos`)
|
||||||
|
- system_tray (from `Flutter/ephemeral/.symlinks/plugins/system_tray/macos`)
|
||||||
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||||
|
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
|
||||||
|
- window_size (from `Flutter/ephemeral/.symlinks/plugins/window_size/macos`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- FMDB
|
- FMDB
|
||||||
- ReachabilitySwift
|
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
|
app_links:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/app_links/macos
|
||||||
audio_service:
|
audio_service:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/audio_service/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/audio_service/macos
|
||||||
audio_session:
|
audio_session:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/audio_session/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/audio_session/macos
|
||||||
audioplayers_darwin:
|
device_info_plus:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
|
||||||
bitsdojo_window_macos:
|
file_selector_macos:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/bitsdojo_window_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos
|
||||||
connectivity_plus_macos:
|
flutter_secure_storage_macos:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos
|
||||||
FlutterMacOS:
|
FlutterMacOS:
|
||||||
:path: Flutter/ephemeral
|
:path: Flutter/ephemeral
|
||||||
macos_ui:
|
local_notifier:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/macos_ui/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/local_notifier/macos
|
||||||
|
media_kit_libs_macos_audio:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_audio/macos
|
||||||
|
media_kit_native_event_loop:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_native_event_loop/macos
|
||||||
metadata_god:
|
metadata_god:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/metadata_god/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/metadata_god/macos
|
||||||
package_info_plus_macos:
|
package_info_plus:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
||||||
path_provider_macos:
|
path_provider_foundation:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
|
||||||
shared_preferences_macos:
|
screen_retriever:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos
|
||||||
|
shared_preferences_foundation:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
|
||||||
sqflite:
|
sqflite:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos
|
||||||
|
system_theme:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/system_theme/macos
|
||||||
|
system_tray:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/system_tray/macos
|
||||||
url_launcher_macos:
|
url_launcher_macos:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||||
|
window_manager:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
|
||||||
|
window_size:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/window_size/macos
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
|
app_links: 4481ed4d71f384b0c3ae5016f4633aa73d32ff67
|
||||||
audio_service: b88ff778e0e3915efd4cd1a5ad6f0beef0c950a9
|
audio_service: b88ff778e0e3915efd4cd1a5ad6f0beef0c950a9
|
||||||
audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72
|
audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72
|
||||||
audioplayers_darwin: dcad41de4fbd0099cb3749f7ab3b0cb8f70b810c
|
device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
|
||||||
bitsdojo_window_macos: 44e3b8fe3dd463820e0321f6256c5b1c16bb6a00
|
file_selector_macos: 468fb6b81fac7c0e88d71317f3eec34c3b008ff9
|
||||||
connectivity_plus_macos: f6e86fd000e971d361e54b5afcadc8c8fa773308
|
flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea
|
||||||
FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811
|
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
macos_ui: 125c911559d646194386d84c017ad6819122e2db
|
local_notifier: e9506bc66fc70311e8bc7291fb70f743c081e4ff
|
||||||
metadata_god: 55a71136c95eb75ec28142f6fbfc2bcff6f881b1
|
media_kit_libs_macos_audio: 3871782a4f3f84c77f04d7666c87800a781c24da
|
||||||
package_info_plus_macos: f010621b07802a241d96d01876d6705f15e77c1c
|
media_kit_native_event_loop: 7321675377cb9ae8596a29bddf3a3d2b5e8792c5
|
||||||
path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19
|
metadata_god: eceae399d0020475069a5cebc35943ce8562b5d7
|
||||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
|
||||||
shared_preferences_macos: a64dc611287ed6cbe28fd1297898db1336975727
|
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
||||||
|
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
|
||||||
|
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
||||||
sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea
|
sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea
|
||||||
url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3
|
system_theme: c7b9f6659a5caa26c9bc2284da096781e9a6fcbc
|
||||||
|
system_tray: e53c972838c69589ff2e77d6d3abfd71332f9e5d
|
||||||
|
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
|
||||||
|
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
|
||||||
|
window_size: 339dafa0b27a95a62a843042038fa6c3c48de195
|
||||||
|
|
||||||
PODFILE CHECKSUM: a884f6dd3f7494f3892ee6c81feea3a3abbf9153
|
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
|
||||||
|
|
||||||
COCOAPODS: 1.11.3
|
COCOAPODS: 1.14.3
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 51;
|
objectVersion = 54;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXAggregateTarget section */
|
/* Begin PBXAggregateTarget section */
|
||||||
@ -208,7 +208,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 0920;
|
LastSwiftUpdateCheck = 0920;
|
||||||
LastUpgradeCheck = 1300;
|
LastUpgradeCheck = 1430;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
33CC10EC2044A3C60003C045 = {
|
33CC10EC2044A3C60003C045 = {
|
||||||
@ -261,6 +261,7 @@
|
|||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
3399D490228B24CF009A79C7 /* ShellScript */ = {
|
3399D490228B24CF009A79C7 /* ShellScript */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
alwaysOutOfDate = 1;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
@ -409,7 +410,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
@ -431,7 +432,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
@ -489,7 +490,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
@ -536,7 +537,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
@ -558,7 +559,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@ -579,7 +580,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1300"
|
LastUpgradeVersion = "1430"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@ -1 +1,86 @@
|
|||||||
{}
|
{
|
||||||
|
"ar": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"bn": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ca": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"de": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"es": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"fa": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"fr": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"hi": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"it": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ja": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"nl": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"pl": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"pt": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ru": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"tr": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"uk": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
],
|
||||||
|
|
||||||
|
"zh": [
|
||||||
|
"step_3_steps",
|
||||||
|
"step_4_steps"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user