Skip to content

Commit

Permalink
Basic last.fm integration
Browse files Browse the repository at this point in the history
  • Loading branch information
CosmicRaptor committed Nov 6, 2024
1 parent e305900 commit a2b3c22
Show file tree
Hide file tree
Showing 10 changed files with 432 additions and 67 deletions.
5 changes: 5 additions & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ const kRadioIndex = 'radioIndex';
const kPodcastIndex = 'podcastIndex';
const kNeverShowImportFails = 'neverShowImportFails';
const kEnableDiscordRPC = 'enableDiscordRPC';
const kEnableLastFmScrobbling = 'enableLastFmScrobbling';
const kLastFmApiKey = 'lastFmApiKey';
const klastFmSecret = 'lastFmSecret';
const kLastFmSessionKey = 'lastFmSessionKey';
const kLastFmUsername = 'lastFmUsername';
const kLastCountryCode = 'lastCountryCode';
const kLastLanguageCode = 'lastLanguageCode';
const kSearchResult = 'searchResult';
Expand Down
34 changes: 31 additions & 3 deletions lib/expose/expose_service.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import 'dart:async';

import 'package:flutter_discord_rpc/flutter_discord_rpc.dart';
import 'package:lastfm/lastfm.dart';

class ExposeService {
ExposeService({required FlutterDiscordRPC? discordRPC})
: _discordRPC = discordRPC;
ExposeService({
required FlutterDiscordRPC? discordRPC,
required LastFMAuthorized? lastFm,
required bool lastFmEnabled,
})
: _discordRPC = discordRPC, _lastFm = lastFm, _lastFmEnabled = lastFmEnabled;

final FlutterDiscordRPC? _discordRPC;
final LastFMAuthorized? _lastFm;
final bool _lastFmEnabled;
final _errorController = StreamController<String?>.broadcast();
Stream<String?> get discordErrorStream => _errorController.stream;
Stream<bool> get isDiscordConnectedStream =>
Expand All @@ -24,6 +31,12 @@ class ExposeService {
additionalInfo: additionalInfo,
imageUrl: imageUrl,
);
if(_lastFmEnabled){
await _exposeTitleToLastfm(
title: title,
artist: artist,
);
}
}

Future<void> _exposeTitleToDiscord({
Expand Down Expand Up @@ -54,6 +67,21 @@ class ExposeService {
}
}

Future<void> _exposeTitleToLastfm({
required String title,
required String artist,
}) async{
try {
await _lastFm?.scrobble(
track: title,
artist: artist,
startTime: DateTime.now(),
);
} on Exception catch (e) {
_errorController.add(e.toString());
}
}

Future<void> connect() async {
await connectToDiscord();
}
Expand All @@ -78,4 +106,4 @@ class ExposeService {
await disconnectFromDiscord();
await _errorController.close();
}
}
}
6 changes: 6 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,12 @@
"exposeOnlineHeadline": "Expose your listening activity online",
"exposeToDiscordTitle": "Discord",
"exposeToDiscordSubTitle": "The artist and title of the song/station/podcast you are currently listening to are shared.",
"exposeToLastfmTitle": "Last.fm",
"exposeToLastfmSubTitle": "The artist and title of the song/station/podcast you are currently listening to are shared.",
"lastfmApiKey": "Last.fm API key",
"lastfmSecret": "Last.fm secret",
"lastfmApiKeyEmpty": "Please enter an API key",
"lastfmSecretEmpty": "Please enter the shared secret",
"featureDisabledOnPlatform": "This feature is currently disabled for this operating system.",
"regionNone": "None",
"regionAfghanistan": "Afghanistan",
Expand Down
41 changes: 38 additions & 3 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_discord_rpc/flutter_discord_rpc.dart';
import 'package:github/github.dart';
import 'package:gtk/gtk.dart';
import 'package:lastfm/lastfm.dart';
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:package_info_plus/package_info_plus.dart';
Expand Down Expand Up @@ -107,10 +108,44 @@ void registerServicesAndViewModels({
),
dispose: (s) => s.dispose(),
)
..registerFactory<LastFM>(
(){
final apiKey = sharedPreferences.getString(kLastFmApiKey) ?? '';
final apiSecret = sharedPreferences.getString(klastFmSecret) ?? '';
final sessionKey = sharedPreferences.getString(kLastFmSessionKey);
final username = sharedPreferences.getString(kLastFmUsername);

if (sessionKey != null && username != null) {
return LastFMAuthorized(
apiKey, secret: apiSecret,
sessionKey: sessionKey,
username: username,
);
} else {
return LastFMUnauthorized(apiKey, apiSecret);
}
}
)
..registerLazySingleton<ExposeService>(
() => ExposeService(
discordRPC: allowDiscordRPC ? di<FlutterDiscordRPC>() : null,
),
(){
final sessionKey = sharedPreferences.getString(kLastFmSessionKey);
final lastFMEnabled =
sharedPreferences.getBool(kEnableLastFmScrobbling) ?? false;
if(sessionKey != null){
return ExposeService(
discordRPC: allowDiscordRPC ? di<FlutterDiscordRPC>() : null,
lastFm: di<LastFM>() as LastFMAuthorized,
lastFmEnabled: lastFMEnabled,
);
}
else {
return ExposeService(
discordRPC: allowDiscordRPC ? di<FlutterDiscordRPC>() : null,
lastFm: null,
lastFmEnabled: lastFMEnabled,
);
}
},
dispose: (s) => s.dispose(),
)
..registerLazySingleton<PlayerService>(
Expand Down
12 changes: 12 additions & 0 deletions lib/settings/settings_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ class SettingsModel extends SafeChangeNotifier {
bool get enableDiscordRPC => _service.enableDiscordRPC;
void setEnableDiscordRPC(bool value) => _service.setEnableDiscordRPC(value);

bool get enableLastFmScrobbling => _service.enableLastFmScrobbling;
String? get lastFmApiKey => _service.lastFmApiKey;
String? get lastFmSecret => _service.lastFmSecret;
String? get lastFmSessionKey => _service.lastFmSessionKey;
String? get lastFmUsername => _service.lastFmUsername;
void setEnableLastFmScrobbling(bool value) =>
_service.setEnableLastFmScrobbling(value);
void setLastFmApiKey(String value) => _service.setLastFmApiKey(value);
void setLastFmSecret(String value) => _service.setLastFmSecret(value);
void setLastFmSessionKey(String value) => _service.setLastFmSessionKey(value);
void setLastFmUsername(String value) => _service.setLastFmUsername(value);

bool get useMoreAnimations => _service.useMoreAnimations;
void setUseMoreAnimations(bool value) => _service.setUseMoreAnimations(value);

Expand Down
42 changes: 42 additions & 0 deletions lib/settings/settings_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,48 @@ class SettingsService {
);
}

bool get enableLastFmScrobbling =>
_preferences.getBool(kEnableLastFmScrobbling) ?? false;
String? get lastFmApiKey => _preferences.getString(kLastFmApiKey);
String? get lastFmSecret => _preferences.getString(klastFmSecret);
String? get lastFmSessionKey => _preferences.getString(kLastFmSessionKey);
String? get lastFmUsername => _preferences.getString(kLastFmUsername);
void setEnableLastFmScrobbling(bool value) {
_preferences.setBool(kEnableLastFmScrobbling, value).then(
(saved) {
if (saved) _propertiesChangedController.add(true);
},
);
}
void setLastFmApiKey(String value) {
_preferences.setString(kLastFmApiKey, value).then(
(saved) {
if (saved) _propertiesChangedController.add(true);
},
);
}
void setLastFmSecret(String value) {
_preferences.setString(klastFmSecret, value).then(
(saved) {
if (saved) _propertiesChangedController.add(true);
},
);
}
void setLastFmSessionKey(String value) {
_preferences.setString(kLastFmSessionKey, value).then(
(saved) {
if (saved) _propertiesChangedController.add(true);
},
);
}
void setLastFmUsername(String value) {
_preferences.setString(kLastFmUsername, value).then(
(saved) {
if (saved) _propertiesChangedController.add(true);
},
);
}

bool get enableDiscordRPC => _preferences.getBool(kEnableDiscordRPC) ?? false;
void setEnableDiscordRPC(bool value) {
_preferences.setBool(kEnableDiscordRPC, value).then(
Expand Down
Loading

0 comments on commit a2b3c22

Please sign in to comment.