Skip to content

Commit

Permalink
Implement visualizer selection and seeker swipe preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaysce committed Nov 6, 2021
1 parent 9de210f commit cc48001
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 25 deletions.
4 changes: 4 additions & 0 deletions Jukebox.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
E80E4CB52727F763000F9D74 /* Seeker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E80E4CB42727F763000F9D74 /* Seeker.swift */; };
E80E4CB827281297000F9D74 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E80E4CB727281297000F9D74 /* NetworkManager.swift */; };
E82271BC2735514400D1795D /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = E82271BB2735514400D1795D /* Constants.swift */; };
E82271C3273567F000D1795D /* VisualizerStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E82271C2273567F000D1795D /* VisualizerStyle.swift */; };
E84A17382728E6F1005F8CB4 /* PromiseKit in Frameworks */ = {isa = PBXBuildFile; productRef = E84A17372728E6F1005F8CB4 /* PromiseKit */; };
E84A173B2728EAC3005F8CB4 /* LyricsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84A173A2728EAC3005F8CB4 /* LyricsView.swift */; };
E84A173D2728F490005F8CB4 /* SpotifyClientCredentials.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84A173C2728F490005F8CB4 /* SpotifyClientCredentials.swift */; };
Expand Down Expand Up @@ -62,6 +63,7 @@
E80E4CB42727F763000F9D74 /* Seeker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Seeker.swift; sourceTree = "<group>"; };
E80E4CB727281297000F9D74 /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = "<group>"; };
E82271BB2735514400D1795D /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
E82271C2273567F000D1795D /* VisualizerStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisualizerStyle.swift; sourceTree = "<group>"; };
E84A173A2728EAC3005F8CB4 /* LyricsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LyricsView.swift; sourceTree = "<group>"; };
E84A173C2728F490005F8CB4 /* SpotifyClientCredentials.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpotifyClientCredentials.swift; sourceTree = "<group>"; };
E84A173E2728F4CB005F8CB4 /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -222,6 +224,7 @@
isa = PBXGroup;
children = (
E8F5724427167CAF00C5DF9C /* Track.swift */,
E82271C2273567F000D1795D /* VisualizerStyle.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -336,6 +339,7 @@
E892FE0D272E878600359A64 /* StatusBarAnimation.swift in Sources */,
E8FB63F4272BB97C006F28B8 /* PreferencesView.swift in Sources */,
E8FB63F8272BEF92006F28B8 /* AboutView.swift in Sources */,
E82271C3273567F000D1795D /* VisualizerStyle.swift in Sources */,
E84A173D2728F490005F8CB4 /* SpotifyClientCredentials.swift in Sources */,
E8AF5FC327290EFB00AACF65 /* Secrets.swift in Sources */,
E8F57242271678C800C5DF9C /* PressButtonStyle.swift in Sources */,
Expand Down
13 changes: 13 additions & 0 deletions Jukebox/Models/VisualizerStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// VisualizerStyle.swift
// Jukebox
//
// Created by Sasindu Jayasinghe on 6/11/21.
//

import Foundation

enum VisualizerStyle: Int {
case none = 0
case gradient = 1
}
17 changes: 15 additions & 2 deletions Jukebox/Styles/ChipStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,26 @@ import Foundation
import SwiftUI

struct ChipStyle: ViewModifier {

@AppStorage("visualizerStyle") private var visualizerStyle: VisualizerStyle = .gradient

// Constants
let primaryOpacity = 0.8
let ternaryOpacity = 0.2

func body(content: Content) -> some View {
content
.font(.caption)
.foregroundColor(.white.opacity(0.8))
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
.padding(.vertical, 3)
.padding(.horizontal, 10)
.background(Color.white.opacity(0.2))
.background(
visualizerStyle != .none
? Color.white.opacity(ternaryOpacity)
: Color.primary.opacity(ternaryOpacity))
.cornerRadius(20)
}
}
Expand Down
46 changes: 37 additions & 9 deletions Jukebox/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import SwiftUI

struct ContentView: View {

// User Defaults
@AppStorage("visualizerStyle") private var visualizerStyle: VisualizerStyle = .gradient

// View Model
@ObservedObject var contentViewVM: ContentViewModel

Expand All @@ -17,19 +20,28 @@ struct ContentView: View {
@State private var playbackScale = 1.0
@State private var lyricsScale = 1.2

// Constants
let primaryOpacity = 0.8
let secondaryOpacity = 0.4
let ternaryOpacity = 0.2

var body: some View {

ZStack {
// TODO: Visualizer View
MetalView(popoverIsShown: contentViewVM.popoverIsShown).padding(-80)
if visualizerStyle == .gradient {
MetalView(popoverIsShown: contentViewVM.popoverIsShown).padding(-80)
}

VStack(spacing: 16) {
// Media details
HStack {
// Album art image
ZStack {
Rectangle()
.foregroundColor(.white.opacity(0.2))
.foregroundColor(
visualizerStyle != .none
? .white.opacity(ternaryOpacity)
: .primary.opacity(ternaryOpacity))
.frame(width: 80, height: 80)
.cornerRadius(8)

Expand All @@ -43,13 +55,19 @@ struct ContentView: View {
// Track details
VStack(alignment: .leading) {
Text(contentViewVM.track.title)
.foregroundColor(.white).opacity(0.8)
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
.font(.system(size: 20, weight: .bold))
.lineLimit(1)
Text(contentViewVM.track.artist)
.font(.headline)
.lineLimit(1)
.foregroundColor(.white).opacity(0.4)
.foregroundColor(
visualizerStyle != .none
? .white.opacity(secondaryOpacity)
: .primary.opacity(secondaryOpacity))

Spacer()

Expand All @@ -75,8 +93,9 @@ struct ContentView: View {
}
.pressButtonStyle()
}
.padding(.bottom, 4)
}
.padding(.vertical, 6)
.frame(width: .infinity, height: 80)

Spacer()
}
Expand All @@ -97,7 +116,10 @@ struct ContentView: View {
} label: {
Image(systemName: "backward.fill")
.font(.system(size: 20))
.foregroundColor(.white).opacity(0.8)
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
}
.pressButtonStyle()

Expand All @@ -106,7 +128,10 @@ struct ContentView: View {
} label: {
Image(systemName: contentViewVM.isPlaying ? "pause.fill" : "play.fill")
.font(.system(size: 30))
.foregroundColor(.white).opacity(0.8)
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
.frame(width: 32, height: 32)
}
.pressButtonStyle()
Expand All @@ -116,7 +141,10 @@ struct ContentView: View {
} label: {
Image(systemName: "forward.fill")
.font(.system(size: 20))
.foregroundColor(.white).opacity(0.8)
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
}
.pressButtonStyle()
}
Expand Down
17 changes: 15 additions & 2 deletions Jukebox/Views/LyricsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@ import SwiftUI

struct LyricsView: View {

// User Defaults
@AppStorage("visualizerStyle") private var visualizerStyle: VisualizerStyle = .gradient

// Properties
let lyrics: String
@Binding var showingLyrics: Bool
@Binding var playbackScale: Double
@Binding var lyricsScale: Double

// Constants
let primaryOpacity = 0.8

var body: some View {
ZStack {
VStack {
Expand All @@ -24,7 +31,10 @@ struct LyricsView: View {
lyricsScale = 1.2
} label: {
Image(systemName: "xmark.circle.fill")
.foregroundColor(.white.opacity(0.8))
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
}
.pressButtonStyle()
Spacer()
Expand All @@ -34,7 +44,10 @@ struct LyricsView: View {
VStack(alignment: .center) {
Text(lyrics)
.multilineTextAlignment(.center)
.foregroundColor(.white.opacity(0.8))
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
.font(.system(size: 20, weight: .bold))
}
.padding(22)
Expand Down
21 changes: 14 additions & 7 deletions Jukebox/Views/PreferencesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,12 @@ struct AppInfo: View {

struct PreferencePanes: View {

private var visualizers = ["None", "Gradient", "Waves", "Abstract"]
@State private var launchAtLogin = false
@State private var selectedVisualization = 1
@AppStorage("visualizerStyle") private var visualizerStyle = VisualizerStyle.gradient.rawValue
@AppStorage("swipeToSeek") private var swipeToSeek = false

@State private var dummy = false

private var visualizers = ["None", "Gradient"]

var body: some View {
VStack(alignment: .leading, spacing: 0) {
Expand All @@ -111,7 +114,8 @@ struct PreferencePanes: View {
.font(.title2)
.fontWeight(.semibold)

Toggle("Launch Jukebox on login", isOn: $launchAtLogin)
Toggle("Launch Jukebox on login", isOn: $dummy)
Toggle("Swipe to seek on trackpad (Experimental)", isOn: $swipeToSeek)
}
.padding()
.frame(width: geo.size.width, height: geo.size.height / 3, alignment: .topLeading)
Expand All @@ -123,8 +127,8 @@ struct PreferencePanes: View {
.font(.title2)
.fontWeight(.semibold)

Toggle("Disable menu bar animation", isOn: $launchAtLogin)
Toggle("Disable menu bar marquee text", isOn: $launchAtLogin)
Toggle("Disable menu bar animation", isOn: $dummy)
Toggle("Disable menu bar marquee text", isOn: $dummy)

}
.padding()
Expand All @@ -137,11 +141,14 @@ struct PreferencePanes: View {
.font(.title2)
.fontWeight(.semibold)

Picker("Style", selection: $selectedVisualization) {
Picker("Style", selection: $visualizerStyle) {
ForEach(0..<visualizers.count) { index in
Text(visualizers[index]).tag(index)
}
}
.onChange(of: visualizerStyle) { val in
visualizerStyle = val
}

}
.padding()
Expand Down
34 changes: 29 additions & 5 deletions Jukebox/Views/Seeker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,41 @@ import SwiftUI

struct Seeker: View {

// User Defaults
@AppStorage("visualizerStyle") private var visualizerStyle: VisualizerStyle = .gradient
@AppStorage("swipeToSeek") private var swipeToSeek = false

// Properties
var trackDuration: Double
@Binding var seekerPosition: Double
let onEditingChanged: (Bool) -> Void

// States for animations
@State private var seekerHeight: CGFloat = 4

// Constants
let primaryOpacity = 0.6
let ternaryOpacity = 0.2

var body: some View {
GeometryReader { geo in
VStack {
ZStack(alignment: .leading) {
Rectangle()
.foregroundColor(.white.opacity(0.2))
.foregroundColor(
visualizerStyle != .none
? .white.opacity(ternaryOpacity)
: .primary.opacity(ternaryOpacity))
Rectangle()
.foregroundColor(.white.opacity(0.6))
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
.frame(width: geo.size.width * CGFloat(self.seekerPosition / trackDuration))
.animation(.easeInOut, value: self.seekerPosition)
SwipeView(seekerPosition: self.$seekerPosition, onEditingChanged: onEditingChanged)
if swipeToSeek {
SwipeView(seekerPosition: self.$seekerPosition, onEditingChanged: onEditingChanged)
}
}
.frame(width: geo.size.width, height: seekerHeight)
.cornerRadius(6)
Expand All @@ -40,11 +58,17 @@ struct Seeker: View {
}))
HStack {
Text(formatSecondsForDisplay(seekerPosition))
.foregroundColor(.white.opacity(0.6))
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
.font(.caption)
Spacer()
Text(formatSecondsForDisplay(trackDuration))
.foregroundColor(.white.opacity(0.6))
.foregroundColor(
visualizerStyle != .none
? .white.opacity(primaryOpacity)
: .primary.opacity(primaryOpacity))
.font(.caption)
}
}
Expand Down

0 comments on commit cc48001

Please sign in to comment.