Skip to content

Commit

Permalink
implement shortcut grid
Browse files Browse the repository at this point in the history
  • Loading branch information
Lee Jun Kit committed Jun 19, 2021
1 parent 76d1a16 commit c3f7bd3
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 94 deletions.
14 changes: 11 additions & 3 deletions Spottie.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
475798D1266F103100AADF2F /* WebAPIPlaylistTrackObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475798D0266F103100AADF2F /* WebAPIPlaylistTrackObject.swift */; };
475798D3266F12EB00AADF2F /* PersonalizedRecommendationsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475798D2266F12EB00AADF2F /* PersonalizedRecommendationsResponse.swift */; };
475798D5266F1B9B00AADF2F /* WebAPIPlaylistTracksRefObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475798D4266F1B9B00AADF2F /* WebAPIPlaylistTracksRefObject.swift */; };
475EE242267C9306007BEBDC /* ShortcutGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475EE241267C9306007BEBDC /* ShortcutGrid.swift */; };
475EE244267D6659007BEBDC /* ShortcutItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475EE243267D6659007BEBDC /* ShortcutItem.swift */; };
47C56F602679A789003EA20A /* PlayerCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C56F5F2679A789003EA20A /* PlayerCommands.swift */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -135,6 +137,8 @@
475798D0266F103100AADF2F /* WebAPIPlaylistTrackObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebAPIPlaylistTrackObject.swift; sourceTree = "<group>"; };
475798D2266F12EB00AADF2F /* PersonalizedRecommendationsResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersonalizedRecommendationsResponse.swift; sourceTree = "<group>"; };
475798D4266F1B9B00AADF2F /* WebAPIPlaylistTracksRefObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebAPIPlaylistTracksRefObject.swift; sourceTree = "<group>"; };
475EE241267C9306007BEBDC /* ShortcutGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutGrid.swift; sourceTree = "<group>"; };
475EE243267D6659007BEBDC /* ShortcutItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutItem.swift; sourceTree = "<group>"; };
47C56F5F2679A789003EA20A /* PlayerCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerCommands.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -193,7 +197,7 @@
4730615D26565706001E3A1F /* Views */ = {
isa = PBXGroup;
children = (
474BAFBD266B79900006EB16 /* Carousel */,
475EE240267C92EC007BEBDC /* Components */,
4730616626565AF8001E3A1F /* BottomBar */,
4730614F265656ED001E3A1F /* ContentView.swift */,
4730615E2656573B001E3A1F /* Sidebar.swift */,
Expand Down Expand Up @@ -307,13 +311,15 @@
path = API;
sourceTree = "<group>";
};
474BAFBD266B79900006EB16 /* Carousel */ = {
475EE240267C92EC007BEBDC /* Components */ = {
isa = PBXGroup;
children = (
474BAFC0266B84CD0006EB16 /* CarouselRow.swift */,
474BAFC2266B85440006EB16 /* CarouselRowItem.swift */,
475EE241267C9306007BEBDC /* ShortcutGrid.swift */,
475EE243267D6659007BEBDC /* ShortcutItem.swift */,
);
path = Carousel;
path = Components;
sourceTree = "<group>";
};
47C56F5E2679A779003EA20A /* Commands */ = {
Expand Down Expand Up @@ -401,6 +407,7 @@
files = (
475798D5266F1B9B00AADF2F /* WebAPIPlaylistTracksRefObject.swift in Sources */,
47306150265656ED001E3A1F /* ContentView.swift in Sources */,
475EE244267D6659007BEBDC /* ShortcutItem.swift in Sources */,
473061792658A02E001E3A1F /* SpotifyEvent.swift in Sources */,
470201BD265B80970030ECA9 /* FakePlayerViewModel.swift in Sources */,
4730618326590931001E3A1F /* TrackObject.swift in Sources */,
Expand All @@ -410,6 +417,7 @@
4730615F2656573B001E3A1F /* Sidebar.swift in Sources */,
470201CC265CF9610030ECA9 /* RepeatButton.swift in Sources */,
4730618B26591E36001E3A1F /* CoverGroupObject.swift in Sources */,
475EE242267C9306007BEBDC /* ShortcutGrid.swift in Sources */,
4730618926591E16001E3A1F /* DateObject.swift in Sources */,
4730616826565B03001E3A1F /* PlayPauseButton.swift in Sources */,
4730616326565828001E3A1F /* Search.swift in Sources */,
Expand Down
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/API/RecommendationLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@
import Foundation

struct RecommendationLink: Decodable {

var uri: String
var name: String
var images: [WebAPIImageObject]
}
78 changes: 0 additions & 78 deletions Spottie/Views/Carousel/CarouselRow.swift

This file was deleted.

78 changes: 78 additions & 0 deletions Spottie/Views/Components/CarouselRow.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// CarouselRow.swift
// Spottie
//
// Created by Lee Jun Kit on 5/6/21.
//

import SwiftUI

struct CarouselRow: View {
let viewModel: ViewModel
let onItemPressed: (String) -> Void

var body: some View {
if viewModel.groupID.hasPrefix("podcast") {
EmptyView()
} else {
VStack(alignment: .leading) {
Text(viewModel.title)
.font(.title).bold()
.padding(.leading)
viewModel.subtitle.map({
Text($0)
.font(.body)
.foregroundColor(.secondary)
.padding(.leading)
.padding(.bottom, 8)
})
HStack(alignment: .top, spacing: 40) {
ForEach(viewModel.items) { item in
let vm = CarouselRowItem.ViewModel.init(item)
CarouselRowItem(viewModel: vm)
.onTapGesture {
onItemPressed(item.id)
}
}
}
.padding([.leading, .trailing])
}
}

}
}

extension CarouselRow {
enum RenderMode {
case circular
case normal
}

class ViewModel: ObservableObject {
var groupID: String
var title: String
var subtitle: String?
var items: [RecommendationItem]

init(_ recommendationGroup: RecommendationGroup, numberOfItemsToShow: Int) {
self.groupID = recommendationGroup.id

title = recommendationGroup.name
subtitle = recommendationGroup.tagline

let numItems = recommendationGroup.items.count
if (numItems < numberOfItemsToShow) {
items = recommendationGroup.items
} else {
items = Array(recommendationGroup.items[0...numberOfItemsToShow - 1])
}
}
}
}

//struct CarouselRow_Previews: PreviewProvider {
//// static let group = RecommendationGroup()
//// static var previews: some View {
//// CarouselRow(viewModel: <#T##CarouselRow.ViewModel#>.init())
//// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ extension CarouselRowItem {
@Published var isHovering = false
@Published var artworkIsCircle = false

init(_ item: RecommendationItem, artworkIsCircular: Bool) {
artworkIsCircle = artworkIsCircular

init(_ item: RecommendationItem) {
if let data = item.data {
switch data {
case let .album(album):
Expand All @@ -68,19 +66,20 @@ extension CarouselRowItem {
self.title = artist.name
self.subtitle = "Artist"
self.artworkURL = URL(string: artist.images[0].url)!
self.artworkIsCircle = true
case let.playlist(playlist):
self.title = playlist.name
self.subtitle = playlist.description ?? ""
self.artworkURL = URL(string: playlist.images[0].url)!
default:
self.title = ""
self.subtitle = ""
self.artworkURL = URL(string: "https://mosaic.scdn.co/640/ab67616d00001e020b7c6d46885f7434c99e6d8bab67616d00001e0244bb39545f5d7176080d17aeab67616d00001e027679b9d0724cc7421189ac44ab67616d00001e028863bc11d2aa12b54f5aeb36")!
self.artworkURL = URL(string: "https://misc.scdn.co/liked-songs/liked-songs-640.png")!
}
} else {
self.title = ""
self.subtitle = ""
self.artworkURL = URL(string: "https://mosaic.scdn.co/640/ab67616d00001e020b7c6d46885f7434c99e6d8bab67616d00001e0244bb39545f5d7176080d17aeab67616d00001e027679b9d0724cc7421189ac44ab67616d00001e028863bc11d2aa12b54f5aeb36")!
self.artworkURL = URL(string: "https://misc.scdn.co/liked-songs/liked-songs-640.png")!
}
}
}
Expand Down
43 changes: 43 additions & 0 deletions Spottie/Views/Components/ShortcutGrid.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// ShortcutsGrid.swift
// Spottie
//
// Created by Lee Jun Kit on 18/6/21.
//

import SwiftUI
import SDWebImageSwiftUI

struct ShortcutGrid: View {
let items: [RecommendationItem]
let onItemPressed: (String) -> Void
var gridItemLayout = Array(repeating: GridItem(.flexible(), spacing: 20), count: 3)

var body: some View {
VStack(alignment: .leading) {
Text("Good Morning")
.font(.largeTitle).bold()
.padding(.leading)
LazyVGrid(columns: gridItemLayout, spacing: 20) {
ForEach(items) { item in
ShortcutItem(
itemHeight: 80,
viewModel: ShortcutItem.ViewModel(item)
)
.onTapGesture {
onItemPressed(item.id)
}
.frame(height: 80)
}
}
.padding([.leading, .trailing])
}

}
}

//struct ShortcutsGrid_Previews: PreviewProvider {
// static var previews: some View {
// ShortcutGrid()
// }
//}
74 changes: 74 additions & 0 deletions Spottie/Views/Components/ShortcutItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// ShortcutItem.swift
// Spottie
//
// Created by Lee Jun Kit on 19/6/21.
//

import SwiftUI
import SDWebImageSwiftUI

struct ShortcutItem: View {
var itemHeight: CGFloat
var viewModel: ViewModel

@State private var isHovering = false

var body: some View {
HStack {
WebImage(url: viewModel.artworkURL)
.resizable()
.frame(width: itemHeight, height: itemHeight)
.aspectRatio(1.0, contentMode: .fill)
Text(viewModel.title).bold()
.padding(.leading)
Spacer()
}
.background(
Color(NSColor.alternatingContentBackgroundColors[1])
.opacity(isHovering ? 1.0 : 0.3)
)
.onHover { hovering in
isHovering = hovering
}
}
}

extension ShortcutItem {
class ViewModel {
var title: String
var artworkURL: URL

init(_ item: RecommendationItem) {
if let data = item.data {
switch data {
case let .album(album):
self.title = album.name
self.artworkURL = album.getArtworkURL()!
case let .artist(artist):
self.title = artist.name
self.artworkURL = URL(string: artist.images[0].url)!
case let.playlist(playlist):
self.title = playlist.name
self.artworkURL = URL(string: playlist.images[0].url)!
case let .link(link):
self.title = link.name
self.artworkURL = URL(string: link.images[0].url)!
}
} else {
self.title = "Unknown"
self.artworkURL = URL(string: "https://misc.scdn.co/liked-songs/liked-songs-640.png")!
}
}
}
}

//struct ShortcutItem_Previews: PreviewProvider {
// static var previews: some View {
// ShortcutItem(
// itemHeight: 80,
// title: "Liked Songs",
// imageURL: URL(string: "https://misc.scdn.co/liked-songs/liked-songs-640.png")!
// )
// }
//}
Loading

0 comments on commit c3f7bd3

Please sign in to comment.