Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/API/musify.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,9 @@ Future<bool> makeSongOffline(dynamic song, {bool fromPlaylist = false}) async {
return false;
}

song['audioBitrate'] = '${audioManifest.bitrate.kiloBitsPerSecond} kbps';
song['audioCodec'] = audioManifest.codec.mimeType;

final stream = _yt.videos.streamsClient.get(audioManifest);
final fileStream = audioFile.openWrite();
await stream.pipe(fileStream);
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_ar.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "تعيين المؤقت",
"settingChangedMsg": "تم تغيير الإعداد",
"settings": "الإعدادات",
"share": "مشاركة",
"sleepTimerCancelled": "تم إلغاء مؤقت النوم",
"sleepTimerSet": "ضبط مؤقت السكون",
"songAdded": "تمت إضافة الأغنية بنجاح!",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Timer festlegen",
"settingChangedMsg": "Einstellung geändert",
"settings": "Einstellungen",
"share": "Teilen",
"sleepTimerCancelled": "Sleep-Timer abgebrochen",
"sleepTimerSet": "Sleep-Timer",
"songAdded": "Song erfolgreich hinzugefügt",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_el.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Ορισμός χρονομέτρου",
"settingChangedMsg": "Η ρύθμιση άλλαξε",
"settings": "Ρυθμίσεις",
"share": "Κοινοποίηση",
"sleepTimerCancelled": "Ο χρονοδιακόπτης ύπνου ακυρώθηκε",
"sleepTimerSet": "Ρύθμιση χρονοδιακόπτη ύπνου",
"songAdded": "Το τραγούδι προστέθηκε με επιτυχία!",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Set timer",
"settingChangedMsg": "Settings updated successfully",
"settings": "Settings",
"share": "Share",
"sleepTimerCancelled": "Sleep timer cancelled",
"sleepTimerSet": "Sleep timer set",
"songAdded": "Song added",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Ajustar temporizador",
"settingChangedMsg": "Ajustes cambiados",
"settings": "Ajustes",
"share": "Compartir",
"sleepTimerCancelled": "Temporizador de apagado cancelado",
"sleepTimerSet": "Temporizador de apagado programado",
"songAdded": "Canción añadida",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_et.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Seadista taimer",
"settingChangedMsg": "Seaded edukalt uuendatud",
"settings": "Seaded",
"share": "Jaga",
"sleepTimerCancelled": "Unetaimer tühistatud",
"sleepTimerSet": "Unetaimer seatud",
"songAdded": "Laul lisatud",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Régler la minuterie",
"settingChangedMsg": "Paramètre modifié",
"settings": "Paramètres",
"share": "Partager",
"sleepTimerCancelled": "Minuterie de sommeil annulée",
"sleepTimerSet": "Minuterie de sommeil réglée",
"songAdded": "Titre ajouté avec succès !",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_he.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "הגדר טיימר",
"settingChangedMsg": "הגדרות עודכנו בהצלחה",
"settings": "הגדרות",
"share": "שתף",
"sleepTimerCancelled": "טיימר שינה בוטל",
"sleepTimerSet": "טיימר שינה הוגדר",
"songAdded": "השיר נוסף",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_hi.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "टाइमर सेट करें",
"settingChangedMsg": "सेटिंग्स सफलतापूर्वक अपडेट हुईं",
"settings": "सेटिंग्स",
"share": "साझा करें",
"sleepTimerCancelled": "Sleep timer cancelled",
"sleepTimerSet": "Sleep timer set",
"songAdded": "गाना जोड़ा गया",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_hu.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Időzítő beállítása",
"settingChangedMsg": "Beállítások sikeresen frissítve",
"settings": "Beállítások",
"share": "Megosztás",
"sleepTimerCancelled": "Elalvás időzítő törölve",
"sleepTimerSet": "Elalvás időzítő beállítva",
"songAdded": "Zene hozzáadva",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_id.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Atur pewaktu",
"settingChangedMsg": "Pengaturan berhasil diubah",
"settings": "Pengaturan",
"share": "Bagikan",
"sleepTimerCancelled": "Pewaktu tidur dibatalkan",
"sleepTimerSet": "Pewaktu tidur diatur",
"songAdded": "Lagu berhasil ditambahkan",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_it.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Imposta timer",
"settingChangedMsg": "Impostazioni cambiate",
"settings": "Impostazioni",
"share": "Condividi",
"sleepTimerCancelled": "Timer di sospensione annullato",
"sleepTimerSet": "Timer di spegnimento impostato",
"songAdded": "Brano aggiunto con successo",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_ja.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "タイマーを設定",
"settingChangedMsg": "設定を変更しました",
"settings": "設定",
"share": "共有",
"sleepTimerCancelled": "スリープタイマーをキャンセルしました",
"sleepTimerSet": "スリープタイマーを設定",
"songAdded": "曲を追加しました",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_ko.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "타이머 설정",
"settingChangedMsg": "설정이 업데이트되었음",
"settings": "설정",
"share": "공유",
"sleepTimerCancelled": "수면 타이머가 취소되었음",
"sleepTimerSet": "수면 타이머가 설정되었음",
"songAdded": "노래가 추가되었음",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_pl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Ustaw minutnik",
"settingChangedMsg": "Ustawienie zostało zmienione",
"settings": "Ustawienia",
"share": "Udostępnij",
"sleepTimerCancelled": "Wyłącznik czasowy został anulowany",
"sleepTimerSet": "Czas uśpienia ustawiony",
"songAdded": "Utwór pomyślnie dodany!",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_pt.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Definir tempo",
"settingChangedMsg": "Configurações atualizadas",
"settings": "Configurações",
"share": "Compartilhar",
"sleepTimerCancelled": "Temporizador de sono cancelado",
"sleepTimerSet": "Temporizador de sono ativado",
"songAdded": "Música adicionada",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_ru.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Установить таймер",
"settingChangedMsg": "Параметр изменён",
"settings": "Настройки",
"share": "Поделиться",
"sleepTimerCancelled": "Таймер сна отменен",
"sleepTimerSet": "Таймер сна установлен",
"songAdded": "Трек успешно добавлен!",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_sv.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Ställ in timern",
"settingChangedMsg": "Inställningarna har uppdaterats",
"settings": "Inställningar",
"share": "Dela",
"sleepTimerCancelled": "Insomningstimern avbruten",
"sleepTimerSet": "Insomningstimern inställd",
"songAdded": "Låt tillagd",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_tr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Zamanlayıcı Ayarla",
"settingChangedMsg": "Ayarlar başarıyla güncellendi",
"settings": "Ayarlar",
"share": "Paylaş",
"sleepTimerCancelled": "Uyku zamanlayıcısı iptal edildi",
"sleepTimerSet": "Uyku zamanlayıcısı ayarlandı",
"songAdded": "Parça Eklendi",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_uk.arb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"setTimer": "Встановити таймер",
"settingChangedMsg": "Налаштування змінено",
"settings": "Налаштування",
"share": "Поділитися",
"sleepTimerCancelled": "Таймер сну скасовано",
"sleepTimerSet": "Таймер сну встановлено",
"songAdded": "Пісня успішно додана!",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_zh-Hant.arb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
"setTimer": "設置計時器",
"settingChangedMsg": "設置更新成功",
"settings": "設置",
"share": "Share",
"sleepTimerCancelled": "Sleep timer cancelled",
"sleepTimerSet": "Sleep timer set",
"songAdded": "歌曲已添加",
Expand Down
1 change: 1 addition & 0 deletions lib/localization/app_zh.arb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
"setTimer": "设置计时器",
"settingChangedMsg": "设置更新成功",
"settings": "设置",
"share": "分享",
"sleepTimerCancelled": "Sleep timer cancelled",
"sleepTimerSet": "Sleep timer set",
"songAdded": "歌曲已添加",
Expand Down
33 changes: 32 additions & 1 deletion lib/screens/now_playing_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import 'package:musify/API/musify.dart';
import 'package:musify/extensions/l10n.dart';
import 'package:musify/main.dart';
import 'package:musify/models/position_data.dart';
import 'package:musify/services/io_service.dart';
import 'package:musify/services/settings_manager.dart';
import 'package:musify/utilities/common_variables.dart';
import 'package:musify/utilities/flutter_bottom_sheet.dart';
Expand All @@ -39,6 +40,7 @@ import 'package:musify/widgets/playback_icon_button.dart';
import 'package:musify/widgets/song_artwork.dart';
import 'package:musify/widgets/song_bar.dart';
import 'package:musify/widgets/spinner.dart';
import 'package:share_plus/share_plus.dart';

final _lyricsController = FlipCardController();

Expand Down Expand Up @@ -666,6 +668,34 @@ class BottomActionsRow extends StatelessWidget {
final double iconSize;
final bool isLargeScreen;

Widget _buildShareButton(
ValueNotifier<bool> songOfflineStatus,
Color primaryColor,
) {
return Builder(
builder: (ctx) => IconButton.filledTonal(
icon: Icon(Icons.share, color: primaryColor),
iconSize: iconSize,
onPressed: () async {
try {
final song = mediaItemToMap(metadata);

if (!songOfflineStatus.value) {
songOfflineStatus.value = await makeSongOffline(song);
}

if (songOfflineStatus.value) {
final file = await FilePaths.temporalFileForSharing(song);
await Share.shareXFiles([XFile(file.path)]);
}
} catch (e) {
logger.log('Error sharing song', e, null);
}
},
),
);
}

Widget _buildOfflineButton(ValueNotifier<bool> status, Color primaryColor) {
return ValueListenableBuilder<bool>(
valueListenable: status,
Expand Down Expand Up @@ -734,8 +764,9 @@ class BottomActionsRow extends StatelessWidget {
: [];
return Wrap(
alignment: WrapAlignment.center,
spacing: 8,
spacing: 4,
children: [
_buildShareButton(songOfflineStatus, _primaryColor),
_buildOfflineButton(songOfflineStatus, _primaryColor),
if (!offlineMode.value) _buildAddToPlaylistButton(_primaryColor),
if (queue.isNotEmpty && !isLargeScreen)
Expand Down
18 changes: 18 additions & 0 deletions lib/services/io_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
*/

import 'dart:io';
import 'dart:math';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';

late String applicationDirPath;

Expand Down Expand Up @@ -54,4 +57,19 @@ class FilePaths {
await artworksDirectory.create(recursive: true);
}
}

static Future<File> temporalFileForSharing(dynamic song) async {
final originalFile = File(song['audioPath']);

final safeTitle = (song['title'] ?? 'song')
.toString()
.replaceAll(RegExp(r'[<>:"/\\|?*]'), '_');
final truncated = safeTitle.substring(0, min(20, safeTitle.length));
final newFileName = '$truncated$audioExtension';

final tempDir = await getTemporaryDirectory();
final newFilePath = path.join(tempDir.path, newFileName);

return originalFile.copy(newFilePath);
}
}
33 changes: 23 additions & 10 deletions lib/utilities/mediaitem.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,30 @@
*/

import 'package:audio_service/audio_service.dart';
import 'package:musify/API/musify.dart';
import 'package:musify/services/io_service.dart';

Map mediaItemToMap(MediaItem mediaItem) => {
'id': mediaItem.id,
'ytid': mediaItem.extras!['ytid'],
'album': mediaItem.album.toString(),
'artist': mediaItem.artist.toString(),
'title': mediaItem.title,
'highResImage': mediaItem.artUri.toString(),
'lowResImage': mediaItem.extras!['lowResImage'],
'isLive': mediaItem.extras!['isLive'],
};
Map<String, dynamic> mediaItemToMap(MediaItem mediaItem) {
final ytid = mediaItem.extras!['ytid'];
dynamic audioPath = null;

if (isSongAlreadyOffline(ytid)) {
audioPath = FilePaths.getAudioPath(ytid);
}

return {
'id': mediaItem.id,
'ytid': mediaItem.extras!['ytid'],
'album': mediaItem.album.toString(),
'artist': mediaItem.artist.toString(),
'title': mediaItem.title,
'highResImage': mediaItem.artUri.toString(),
'lowResImage': mediaItem.extras!['lowResImage'],
'isLive': mediaItem.extras!['isLive'],
'audioPath': audioPath,
'isOffline': audioPath != null,
};
}

MediaItem mapToMediaItem(Map song) => MediaItem(
id: song['id'].toString(),
Expand Down
33 changes: 33 additions & 0 deletions lib/widgets/song_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ import 'package:flutter/material.dart';
import 'package:musify/API/musify.dart';
import 'package:musify/extensions/l10n.dart';
import 'package:musify/main.dart';
import 'package:musify/services/io_service.dart';
import 'package:musify/utilities/common_variables.dart';
import 'package:musify/utilities/flutter_toast.dart';
import 'package:musify/utilities/formatter.dart';
import 'package:musify/widgets/no_artwork_cube.dart';
import 'package:share_plus/share_plus.dart';

class SongBar extends StatefulWidget {
const SongBar(
Expand Down Expand Up @@ -222,6 +224,27 @@ class _SongBarState extends State<SongBar> {
case 'offline':
_handleOfflineToggle(context);
break;
case 'share':
_handleShareAction(context);
break;
}
}

void _handleShareAction(BuildContext context) async {
try {
if (!_songOfflineStatus.value) {
_songOfflineStatus.value = await makeSongOffline(widget.song);
}

if (_songOfflineStatus.value) {
final file = await FilePaths.temporalFileForSharing(widget.song);
await Share.shareXFiles([XFile(file.path)]);
}
} catch (e) {
logger.log('Error sharing song', e, null);
if (context.mounted) {
showToast(context, context.l10n!.error);
}
}
}

Expand Down Expand Up @@ -347,6 +370,16 @@ class _SongBarState extends State<SongBar> {
},
),
),
PopupMenuItem<String>(
value: 'share',
child: Row(
children: [
Icon(FluentIcons.share_24_regular, color: primaryColor),
const SizedBox(width: 8),
Text(context.l10n!.share),
],
),
),
];
}
}
Expand Down
Loading