mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-12-08 00:17:29 +00:00
feat: add stream money calculation
This commit is contained in:
parent
858bbbb20d
commit
dcb4c0a018
@ -1,3 +1,8 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
final compactNumberFormatter = NumberFormat.compact();
|
||||
final usdFormatter = NumberFormat.compactCurrency(
|
||||
locale: 'en-US',
|
||||
symbol: r"$",
|
||||
decimalDigits: 2,
|
||||
);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotube/collections/formatters.dart';
|
||||
import 'package:spotube/components/stats/summary/summary_card.dart';
|
||||
import 'package:spotube/extensions/constrains.dart';
|
||||
import 'package:spotube/provider/history/summary.dart';
|
||||
@ -32,7 +33,7 @@ class StatsPageSummarySection extends HookConsumerWidget {
|
||||
title: summary.duration.inMinutes.toDouble(),
|
||||
unit: "minutes",
|
||||
description: 'Listened to music',
|
||||
color: Colors.green,
|
||||
color: Colors.purple,
|
||||
),
|
||||
SummaryCard(
|
||||
title: summary.tracks.toDouble(),
|
||||
@ -40,6 +41,12 @@ class StatsPageSummarySection extends HookConsumerWidget {
|
||||
description: 'Streamed overall',
|
||||
color: Colors.lightBlue,
|
||||
),
|
||||
SummaryCard.unformatted(
|
||||
title: usdFormatter.format(summary.fees.toDouble()),
|
||||
unit: "",
|
||||
description: 'Worth of streams',
|
||||
color: Colors.green,
|
||||
),
|
||||
SummaryCard(
|
||||
title: summary.artists.toDouble(),
|
||||
unit: "artist's",
|
||||
|
||||
@ -4,13 +4,21 @@ import 'package:gap/gap.dart';
|
||||
import 'package:spotube/collections/formatters.dart';
|
||||
|
||||
class SummaryCard extends StatelessWidget {
|
||||
final double title;
|
||||
final String title;
|
||||
final String unit;
|
||||
final String description;
|
||||
|
||||
final MaterialColor color;
|
||||
|
||||
const SummaryCard({
|
||||
SummaryCard({
|
||||
super.key,
|
||||
required double title,
|
||||
required this.unit,
|
||||
required this.description,
|
||||
required this.color,
|
||||
}) : title = compactNumberFormatter.format(title);
|
||||
|
||||
const SummaryCard.unformatted({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.unit,
|
||||
@ -35,7 +43,7 @@ class SummaryCard extends StatelessWidget {
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: compactNumberFormatter.format(title),
|
||||
text: title,
|
||||
style: textTheme.headlineLarge?.copyWith(
|
||||
color: color.shade900,
|
||||
),
|
||||
|
||||
@ -5,7 +5,6 @@ import 'dart:convert';
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/extensions/track.dart';
|
||||
import 'package:spotube/provider/proxy_playlist/proxy_playlist.dart';
|
||||
import 'package:spotube/services/audio_player/loop_mode.dart';
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/extensions/track.dart';
|
||||
import 'package:spotube/services/sourced_track/sourced_track.dart';
|
||||
|
||||
class CurrentPlaylist {
|
||||
|
||||
@ -82,7 +82,7 @@ final connectServerProvider = FutureProvider((ref) async {
|
||||
.toJson(),
|
||||
);
|
||||
channel.sink.add(
|
||||
WebSocketShuffleEvent(await audioPlayer.isShuffled).toJson(),
|
||||
WebSocketShuffleEvent(audioPlayer.isShuffled).toJson(),
|
||||
);
|
||||
channel.sink.add(
|
||||
WebSocketLoopEvent(audioPlayer.loopMode).toJson(),
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotube/provider/history/history.dart';
|
||||
import 'package:spotube/provider/history/state.dart';
|
||||
import 'package:spotube/provider/history/top.dart';
|
||||
|
||||
final playbackHistorySummaryProvider = Provider((ref) {
|
||||
final (:tracks, :albums, :playlists) =
|
||||
@ -43,10 +45,17 @@ final playbackHistorySummaryProvider = Provider((ref) {
|
||||
)
|
||||
.length;
|
||||
|
||||
final tracksThisMonth = ref.watch(
|
||||
playbackHistoryTopProvider(HistoryDuration.days30).select((s) => s.tracks),
|
||||
);
|
||||
|
||||
final streams = tracksThisMonth.fold(0, (acc, el) => acc + el.count);
|
||||
|
||||
return (
|
||||
duration: totalDurationListened,
|
||||
tracks: totalTracksListened,
|
||||
artists: totalArtistsListened,
|
||||
fees: streams * 0.005, // Spotify pays $0.003 to $0.005
|
||||
albums: totalAlbumsListened,
|
||||
playlists: totalPlaylistsListened,
|
||||
);
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:spotube/provider/history/state.dart';
|
||||
|
||||
final playbackHistoryTopDurationProvider =
|
||||
StateProvider((ref) => HistoryDuration.days7);
|
||||
|
||||
final playbackHistoryTopProvider =
|
||||
Provider.family((ref, HistoryDuration durationState) {
|
||||
final grouped = ref.watch(playbackHistoryGroupedProvider);
|
||||
|
||||
@ -11,7 +11,7 @@ class MobileAudioService extends BaseAudioHandler {
|
||||
AudioSession? session;
|
||||
final ProxyPlaylistNotifier playlistNotifier;
|
||||
|
||||
// ignore: invalid_use_of_protected_member
|
||||
// ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member
|
||||
ProxyPlaylist get playlist => playlistNotifier.state;
|
||||
|
||||
MobileAudioService(this.playlistNotifier) {
|
||||
@ -135,7 +135,7 @@ class MobileAudioService extends BaseAudioHandler {
|
||||
playing: audioPlayer.isPlaying,
|
||||
updatePosition: position,
|
||||
bufferedPosition: await audioPlayer.bufferedPosition ?? Duration.zero,
|
||||
shuffleMode: await audioPlayer.isShuffled == true
|
||||
shuffleMode: audioPlayer.isShuffled == true
|
||||
? AudioServiceShuffleMode.all
|
||||
: AudioServiceShuffleMode.none,
|
||||
repeatMode: (audioPlayer.loopMode).toAudioServiceRepeatMode(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user