Skip to content

Commit

Permalink
feat(profile): add trop tracks
Browse files Browse the repository at this point in the history
  • Loading branch information
angristan committed Jul 26, 2021
1 parent 2046f28 commit 4d4b5dc
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 28 deletions.
4 changes: 4 additions & 0 deletions firstfm.xcodeproj/project.pbxproj
Expand Up @@ -32,6 +32,7 @@
822E9A9426A97B3600C5307B /* TagTopArtistsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 822E9A9326A97B3600C5307B /* TagTopArtistsResponse.swift */; };
822E9A9626A97B7200C5307B /* TagViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 822E9A9526A97B7200C5307B /* TagViewModel.swift */; };
8240989C26ADF67F00A789D9 /* ArtistBioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8240989B26ADF67E00A789D9 /* ArtistBioView.swift */; };
82428B2426AEC53C00AAC835 /* TopUserTracksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82428B2326AEC53C00AAC835 /* TopUserTracksView.swift */; };
82505CDF2675074E00CCCB58 /* ArtistRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82505CDC2675074E00CCCB58 /* ArtistRow.swift */; };
82505CE02675074E00CCCB58 /* ChartListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82505CDD2675074E00CCCB58 /* ChartListView.swift */; };
82505CE12675074E00CCCB58 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82505CDE2675074E00CCCB58 /* ContentView.swift */; };
Expand Down Expand Up @@ -125,6 +126,7 @@
822E9A9326A97B3600C5307B /* TagTopArtistsResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagTopArtistsResponse.swift; sourceTree = "<group>"; };
822E9A9526A97B7200C5307B /* TagViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagViewModel.swift; sourceTree = "<group>"; };
8240989B26ADF67E00A789D9 /* ArtistBioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistBioView.swift; sourceTree = "<group>"; };
82428B2326AEC53C00AAC835 /* TopUserTracksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopUserTracksView.swift; sourceTree = "<group>"; };
82505CDC2675074E00CCCB58 /* ArtistRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArtistRow.swift; sourceTree = "<group>"; };
82505CDD2675074E00CCCB58 /* ChartListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartListView.swift; sourceTree = "<group>"; };
82505CDE2675074E00CCCB58 /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -329,6 +331,7 @@
82B6CCDE26AB1795008AFDEF /* ProfileLoggedOutView.swift */,
82B6CCE226AB800B008AFDEF /* LastUserScrobblesView.swift */,
82B6CCE426AB80B4008AFDEF /* TopUserArtistsView.swift */,
82428B2326AEC53C00AAC835 /* TopUserTracksView.swift */,
);
path = Profile;
sourceTree = "<group>";
Expand Down Expand Up @@ -612,6 +615,7 @@
825F0F8926A4B2E0007BA84B /* ArtistInfoResponse.swift in Sources */,
82C282E826A3332E000E5F41 /* FriendsResponse.swift in Sources */,
822E9A8C26A8CFAC00C5307B /* TrackView.swift in Sources */,
82428B2426AEC53C00AAC835 /* TopUserTracksView.swift in Sources */,
820455E0267ABC930009A418 /* AuthViewModel.swift in Sources */,
82B6CCE126AB2832008AFDEF /* SrobblesLoggedOutView.swift in Sources */,
825F0FC526A74539007BA84B /* TopArtistAlbumsView.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion firstfm/Models/LastFM/Track.swift
Expand Up @@ -5,7 +5,7 @@ struct Track: Codable, Identifiable {

var name: String
var playcount: String
var listeners: String
var listeners: String?
var url: String
var artist: TrackArtist?
var image: [LastFMImage]
Expand Down
83 changes: 71 additions & 12 deletions firstfm/ViewModel/ProfileViewModel.swift
Expand Up @@ -8,29 +8,32 @@ class ProfileViewModel: ObservableObject {
@Published var scrobbles: [ScrobbledTrack] = []
@Published var topArtists: [Artist] = []
@Published var scrobblesPeriodPicked: Int = 5
@Published var topTracksPeriodPicked: Int = 5
@Published var topTracks: [Track] = []
var isFriendsLoading = true
// var isLoading = true
// var isLoading = true
@AppStorage("lastfm_username") var storedUsername: String?
let myValet = getValet()

func getAll(_ username: String) {
// reset()
// reset()

self.getProfile(username)
self.getUserScrobbles()
self.getTopArtists(period: "overall")
self.getTopTracks(period: "overall")
}

func getProfile(_ username: String) {
// self.isLoading = true
// self.isLoading = true

LastFMAPI.request(lastFMMethod: "user.getInfo", args: ["user": username]) { (data: UserInfoResponse?, error) -> Void in
if error != nil {
DispatchQueue.main.async {
FloatingNotificationBanner(title: "Failed to load profile", subtitle: error?.localizedDescription, style: .danger).show()
}
}
// self.isLoading = false
// self.isLoading = false

if let data = data {
DispatchQueue.main.async {
Expand All @@ -41,15 +44,15 @@ class ProfileViewModel: ObservableObject {
}

func getFriends(_ username: String) {
// self.isFriendsLoading = true
// self.isFriendsLoading = true

LastFMAPI.request(lastFMMethod: "user.getFriends", args: ["user": username]) { (data: FriendsResponse?, error) -> Void in
if error != nil {
DispatchQueue.main.async {
FloatingNotificationBanner(title: "Failed to load friends", subtitle: error?.localizedDescription, style: .danger).show()
}
}
// self.isFriendsLoading = false
// self.isFriendsLoading = false

if let data = data {
DispatchQueue.main.async {
Expand All @@ -60,7 +63,7 @@ class ProfileViewModel: ObservableObject {
}

func getUserScrobbles() {
// self.isLoading = true
// self.isLoading = true
let storedToken = try? myValet.string(forKey: "sk")

LastFMAPI.request(lastFMMethod: "user.getRecentTracks", args: [
Expand All @@ -69,7 +72,7 @@ class ProfileViewModel: ObservableObject {
"user": storedUsername ?? "",
"sk": storedToken ?? ""
]) { (data: RecentTracksResponse?, error) -> Void in
// self.isLoading = false
// self.isLoading = false

if error != nil {
DispatchQueue.main.async {
Expand Down Expand Up @@ -157,16 +160,72 @@ class ProfileViewModel: ObservableObject {
// Get image URL for each artist and trigger a View update through the observed object
SpotifyImage.findImage(type: "artist", name: artist.name) { imageURL in
if let imageURL = imageURL {
// DispatchQueue.main.async {
artists[index].image[0].url = imageURL
// }
// DispatchQueue.main.async {
artists[index].image[0].url = imageURL
// }
}
}
}

DispatchQueue.main.async {
self.topArtists = artists
// self.isLoading = false
// self.isLoading = false
}
}
}
}

func getTopTracksForPeriodTag(tag: Int) {
// Reset tracks to show placeholder
self.topTracks = []

switch tag {
case 0:
self.getTopTracks(period: "7day")
case 1:
self.getTopTracks(period: "1month")
case 2:
self.getTopTracks(period: "3month")
case 3:
self.getTopTracks(period: "6month")
case 4:
self.getTopTracks(period: "12month")
default:
self.getTopTracks(period: "overall")
}
}

func getTopTracks(period: String) {
LastFMAPI.request(lastFMMethod: "user.getTopTracks", args: ["user": storedUsername ?? "", "limit": "5", "period": period]) { (data: ArtistTopTracksResponse?, error) -> Void in

if error != nil {
DispatchQueue.main.async {
FloatingNotificationBanner(title: "Failed to load charts", subtitle: error?.localizedDescription, style: .danger).show()
// Force refresh, otherwise pull loader doesn't dismiss itself
self.topTracks = self.topTracks
}
}

if let data = data {
var tracks = data.toptracks.track

for index in tracks.indices where tracks[index].image[0].url == "" {
tracks[index].image[0].url = "https://lastfm.freetls.fastly.net/i/u/64s/4128a6eb29f94943c9d206c08e625904.webp"
}

DispatchQueue.main.async {
self.topTracks = tracks
}

for (index, track) in data.toptracks.track.enumerated() {
SpotifyImage.findImage(type: "track", name: track.name) { imageURL in
if let imageURL = imageURL {
DispatchQueue.main.async {
self.topTracks[index].image[0].url = imageURL
}

}
}
}
}
}
Expand Down
24 changes: 17 additions & 7 deletions firstfm/Views/Profile/ProfileView.swift
Expand Up @@ -77,16 +77,26 @@ struct ProfileView: View {
.frame(width: 350)

LastUserScrobblesView(scrobbles: profile.scrobbles)
.frame(
width: g.size.width - 5,
height: g.size.height * 0.7,
alignment: .center
)
.offset(y: -70)
.frame(
width: g.size.width - 5,
height: g.size.height * 0.7,
alignment: .center
)
.offset(y: -70)

TopUserArtistsView(artists: profile.topArtists)
.environmentObject(profile)
.offset(y: -90)
.offset(y: -100)

TopUserTracksView(tracks: profile.topTracks)
.environmentObject(profile)
.frame(
width: g.size.width - 5,
height: g.size.height * 0.7,
alignment: .center
)
.redacted(reason: profile.topTracks.isEmpty ? .placeholder : [])
.offset(y: -100)
}
.edgesIgnoringSafeArea(.top)
}.edgesIgnoringSafeArea(.top)
Expand Down
52 changes: 52 additions & 0 deletions firstfm/Views/Profile/TopUserTracksView.swift
@@ -0,0 +1,52 @@
import SwiftUI

struct TopUserTracksView: View {
var tracks: [Track]
@EnvironmentObject var vm: ProfileViewModel

var body: some View {
List {
Section {
HStack {
Text("Top tracks").font(.headline)
Spacer()

Menu {
Picker(selection: $vm.topTracksPeriodPicked, label: Text("Period")) {
Text("Last 7 days").tag(0)
Text("Last 30 days").tag(1)
Text("Last 90 days").tag(2)
Text("Last 180 days").tag(3)
Text("Last 365 days").tag(4)
Text("All time").tag(5)
}.onChange(of: vm.topTracksPeriodPicked) {
tag in vm.getTopTracksForPeriodTag(tag: tag)
}
}
label: {
Label("", systemImage: "calendar").foregroundColor(.white)
}
}.unredacted()
if !tracks.isEmpty {
ForEach(tracks, id: \.name) { track in
NavigationLink(
destination: TrackView(track: track),
label: {
TrackRow(track: track)
})
}
} else {
// Placeholder for redacted
ForEach((1...5), id: \.self) {_ in
NavigationLink(
destination: Color(.red),
label: {
TrackRow(track: Track(name: "toto", playcount: "123", listeners: "123", url: "123", artist: nil, image: [LastFMImage(url: "https://lastfm.freetls.fastly.net/i/u/64s/4128a6eb29f94943c9d206c08e625904.webp", size: "lol")]))
})
}
}

}
}.hasScrollEnabled(false)
}
}
9 changes: 1 addition & 8 deletions firstfm/Views/SubViews/TrackRowView.swift
Expand Up @@ -6,8 +6,6 @@ struct TrackRow: View {

var body: some View {
HStack {
// KFImage(URL(string: artist.image[0].url )!).resizable()
// .frame(width: 50, height: 50)
KFImage.url(URL(string: track.image[0].url )!)
.resizable()
.loadImmediately()
Expand All @@ -17,11 +15,6 @@ struct TrackRow: View {
.onFailure { err in
print("Error \(self.track.name): \(err)")
}
// .placeholder {
// ProgressView()
// .frame(width: 50, height: 50)
// .foregroundColor(.gray)
// }
.fade(duration: 0.5)
.cancelOnDisappear(true)
.cornerRadius(5)
Expand All @@ -34,7 +27,7 @@ struct TrackRow: View {
.font(.headline)
.lineLimit(1)
Spacer()
Text("\(Int(track.listeners )?.formatted() ?? "0") listeners")
Text("\(Int(track.playcount ?? "0" )?.formatted() ?? "0") scrobbles")
.font(.subheadline)
.foregroundColor(.gray)
}
Expand Down

0 comments on commit 4d4b5dc

Please sign in to comment.