Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Button hitbox fixes, notch sizing optimalizations, fix text overflow, animations #22

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions boringNotch.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
14D570D52C5F710B0011E668 /* constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D570D42C5F710B0011E668 /* constants.swift */; };
B15063522C63D41A00EBB0E3 /* Image2Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = B15063512C63D41A00EBB0E3 /* Image2Color.swift */; };
B15063542C63E18700EBB0E3 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B15063532C63E18700EBB0E3 /* SettingsView.swift */; };
B1C974342C642B6D0000E707 /* MarqueeTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1C974332C642B6D0000E707 /* MarqueeTextView.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -61,6 +62,7 @@
14D570D42C5F710B0011E668 /* constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = constants.swift; sourceTree = "<group>"; };
B15063512C63D41A00EBB0E3 /* Image2Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image2Color.swift; sourceTree = "<group>"; };
B15063532C63E18700EBB0E3 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
B1C974332C642B6D0000E707 /* MarqueeTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarqueeTextView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -96,6 +98,7 @@
14D570D12C5F6C6A0011E668 /* BoringExtrasMenu.swift */,
1471A8582C6281BD0058408D /* BoringNotchWindow.swift */,
B15063532C63E18700EBB0E3 /* SettingsView.swift */,
B1C974332C642B6D0000E707 /* MarqueeTextView.swift */,
);
path = components;
sourceTree = "<group>";
Expand Down Expand Up @@ -273,6 +276,7 @@
14D570C02C5EA5870011E668 /* AnimatedFace.swift in Sources */,
14D570CB2C5F4B2C0011E668 /* BatteryStatusViewModel.swift in Sources */,
14D570B92C5E98A20011E668 /* drop.swift in Sources */,
B1C974342C642B6D0000E707 /* MarqueeTextView.swift in Sources */,
14D570BE2C5EA0270011E668 /* PlaybackManager.swift in Sources */,
1471639A2C5D35FF0068B555 /* MusicManager.swift in Sources */,
14D570C92C5F38890011E668 /* BoringViewModel.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion boringNotch/boringNotchApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
let windowWidth = window.frame.width
let windowHeight = window.frame.height
let notchCenterX = screenFrame.width / 2
let statusBarHeight: CGFloat = 18
let statusBarHeight: CGFloat = 12
let windowX = notchCenterX - windowWidth / 2
let windowY = screenFrame.height - statusBarHeight - windowHeight / 2

Expand Down
10 changes: 6 additions & 4 deletions boringNotch/components/BoringBattery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ struct BatteryView: View {
.resizable()
.fontWeight(.thin)
.aspectRatio(contentMode: .fit)
.foregroundColor(batteryColor).frame(
.foregroundColor(batteryColor)
.frame(
width: batteryWidth,
height: batteryHeight
)

RoundedRectangle(cornerRadius: 2).fill(batteryColor).frame( width: CGFloat(((CGFloat(CFloat(percentage)) / 100) * (batteryWidth-6.5))),
height: batteryHeight - 21).padding(.leading, 1.75)
RoundedRectangle(cornerRadius: 2)
.fill(batteryColor)
.frame(width: CGFloat(((CGFloat(CFloat(percentage)) / 100) * (batteryWidth - 6.75))), height: batteryHeight - 21.5)
.padding(.leading, 1.75)

if isCharging {
Image(systemName: "bolt.fill").resizable()
Expand All @@ -47,7 +50,6 @@ struct BatteryView: View {
}

}

}
}

Expand Down
23 changes: 16 additions & 7 deletions boringNotch/components/BoringHeader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,29 @@ struct BoringHeader: View {
@State var isCharging: Bool
var body: some View {
HStack {
Text(
vm.headerTitle
)
.contentTransition(.numericText())
Text(vm.headerTitle)
.contentTransition(.numericText())
.font(.system(size: 12, design: .rounded))
.foregroundStyle(.gray)
Spacer()
HStack(spacing: 8){
HStack(spacing: 12){
if vm.currentView != .menu {
Button(
action: {
vm.openMenu()
},
label: {
Image(systemName: "ellipsis").foregroundColor(.white)
}).buttonStyle(PlainButtonStyle()).padding().frame(width: 30, height:30).font(.title)
Capsule()
.fill(.black)
.frame(width: 30, height: 30)
.overlay {
Image(systemName: "ellipsis")
.foregroundColor(.white)
.padding()
.imageScale(.large)
}
})
.buttonStyle(PlainButtonStyle())
}
BoringBatteryView(
batteryPercentage: percentage,
Expand Down
88 changes: 62 additions & 26 deletions boringNotch/components/BoringNotch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct BoringNotch: View {

var body: some View {
ZStack {
NotchShape(cornerRadius: vm.notchState == .open ? vm.sizes.corderRadius.opened.inset: vm.sizes.corderRadius.closed.inset)
NotchShape(cornerRadius: vm.notchState == .open ? vm.sizes.corderRadius.opened.inset : vm.sizes.corderRadius.closed.inset)
.fill(Color.black)
.frame(width: vm.notchState == .open ? vm.sizes.size.opened.width : batteryModel.showChargingInfo ? CGFloat(vm.sizes.size.closed.width!) + CGFloat(100) : vm.sizes.size.closed.width, height: vm.notchState == .open ? vm.sizes.size.opened.height : vm.sizes.size.closed.height)
.animation(.spring(response: 0.7, dampingFraction: 0.8, blendDuration: 0.8), value: batteryModel.showChargingInfo)
Expand All @@ -44,7 +44,7 @@ struct BoringNotch: View {
)
.cornerRadius(vm.notchState == .open ? vm.musicPlayerSizes.image.corderRadius.opened.inset! : vm.musicPlayerSizes.image.corderRadius.closed.inset!)
.scaledToFit()
.padding(.leading, vm.notchState == .open ? 5 : 0)
.padding(.leading, vm.notchState == .open ? 5 : 3)
// Fit the image within the frame
}

Expand All @@ -57,36 +57,66 @@ struct BoringNotch: View {

if vm.currentView != .menu {
if musicManager.isPlaying == true || musicManager.lastUpdated.timeIntervalSinceNow > -vm.waitInterval {
VStack(alignment: .leading, spacing: 12) {
VStack(alignment: .leading, spacing: 2){
VStack(alignment: .leading, spacing: 5) {
VStack(alignment: .leading, spacing: 3){
Text(musicManager.songTitle)
.font(.headline).fontWeight(.regular)
.font(.headline)
.fontWeight(.regular)
.foregroundColor(.white)
.lineLimit(1)
Text(musicManager.artistName)
.font(.caption)
.font(.subheadline)
.foregroundColor(.gray)
.lineLimit(1)
}
HStack(spacing: 15) {
Button(action: {
HStack(spacing: 5) {
Button {
musicManager.previousTrack()
}) {
Image(systemName: "backward.fill")
.foregroundColor(.white).font(.title2)
}.buttonStyle(PlainButtonStyle())
Button(action: {
} label: {
Capsule()
.fill(.black)
.frame(width: 30, height: 30)
.overlay {
Image(systemName: "backward.fill")
.foregroundColor(.white)
.imageScale(.medium)
}
}
Button {
musicManager.togglePlayPause()
}) {
Image(systemName: musicManager.isPlaying ? "pause.fill" : "play.fill")
.foregroundColor(.white).font(.title)
}.buttonStyle(PlainButtonStyle())
Button(action: {
} label: {
Capsule()
.fill(.black)
.frame(width: 30, height: 30)
.overlay {
Image(systemName: musicManager.isPlaying ? "pause.fill" : "play.fill")
.foregroundColor(.white)
.contentTransition(.symbolEffect)
.imageScale(.large)
}
}
Button {
musicManager.nextTrack()
}) {
Image(systemName: "forward.fill")
.foregroundColor(.white).font(.title2)
}.buttonStyle(PlainButtonStyle())
} label: {
Capsule()
.fill(.black)
.frame(width: 30, height: 30)
.overlay {
Capsule()
.fill(.black)
.frame(width: 30, height: 30)
.overlay {
Image(systemName: "forward.fill")
.foregroundColor(.white)
.imageScale(.medium)

}
}
}
}
}.transition(.blurReplace.animation(.spring(.bouncy(duration: 0.3)).delay(vm.notchState == .closed ? 0 : 0.1)))
}
.transition(.blurReplace.animation(.spring(.bouncy(duration: 0.3)).delay(vm.notchState == .closed ? 0 : 0.1)))
.buttonStyle(PlainButtonStyle())
}

if musicManager.isPlaying == false && musicManager.lastUpdated.timeIntervalSinceNow < -vm.waitInterval {
Expand All @@ -108,12 +138,18 @@ struct BoringNotch: View {
if !batteryModel.showChargingInfo && vm.currentView != .menu {

MusicVisualizer(avgColor: musicManager.albumArt.averageColor(), isPlaying: musicManager.isPlaying)
.frame(width: 30).padding(.horizontal, vm.notchState == .open ? 8 : 2)
.frame(width: 30)
.padding(.horizontal, vm.notchState == .open ? 8 : 0)

}
}
}.frame(width: vm.notchState == .open ? 430 : batteryModel.showChargingInfo ? CGFloat(270) + CGFloat(100): 285)
.padding(.horizontal, 10).padding(.vertical, vm.notchState == .open ? 10: 20).padding(.bottom, vm.notchState == .open ?5:0).transition(.blurReplace.animation(.spring(.bouncy(duration: 0.5))))
}
.frame(width: vm.notchState == .open ? 430 : batteryModel.showChargingInfo ? CGFloat(270) + CGFloat(100) : 250)
.padding(.horizontal, 10)
.padding(.vertical, vm.notchState == .open ? 10 : 20)
.padding(.bottom, vm.notchState == .open ? 5 : 0)
.padding(.top, vm.notchState == .closed ? 5 : 0)
.transition(.blurReplace.animation(.spring(.bouncy(duration: 0.5))))
}
.onHover { hovering in
withAnimation(vm.animation) {
Expand Down
53 changes: 53 additions & 0 deletions boringNotch/components/MarqueeTextView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// MarqueeTextView.swift
// boringNotch
//
// Created by Richard Kunkli on 08/08/2024.
//

import SwiftUI

struct Marquee: View {
@State var text: String
var font: Font

@State var storedSize: CGSize = .zero
@State var offset: CGFloat = 0

var body: some View{
ScrollView(.horizontal, showsIndicators: false) {
Text(text)
.font(font)
.offset(x: offset)
}
.disabled(true)
.onAppear {
storedSize = textSize()

(1...15).forEach {_ in
text.append(" ")
}

let timing: Double = (0.02 * storedSize.width)

DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
withAnimation(.linear(duration: timing)){
offset = -storedSize.width
}
}
}
.onReceive(Timer.publish(every: (0.02 * storedSize.width), on: .main, in: .default).autoconnect(), perform: { _ in
offset = 0
withAnimation(.linear(duration: (0.02 * storedSize.width))) {
offset = -storedSize.width
}
})
}

func textSize() -> CGSize {
let attributes = [NSAttributedString.Key.font: font]
let size = (text as NSString).size(withAttributes: attributes)

return size
}
}
19 changes: 12 additions & 7 deletions boringNotch/components/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,13 @@

import SwiftUI

enum settingsEnum {
case general
}

struct SettingsView: View {
@EnvironmentObject var vm: BoringViewModel
@State private var selectedTab: settingsEnum = .general
@State private var selectedTab: SettingsEnum = .general
var body: some View {
TabView(selection: $selectedTab,
content: {
GeneralSettings().tabItem { Label("General", systemImage: "gear") }.tag(settingsEnum.general)
GeneralSettings().tabItem { Label("General", systemImage: "gear") }.tag(SettingsEnum.general)
})
}

Expand All @@ -26,7 +22,16 @@ struct SettingsView: View {
Form {
Section {
Toggle("Enable colored spectrograms", isOn: $vm.coloredSpectrogram.animation())
TextField("Media inactivity timeout", value: $vm.waitInterval, formatter: NumberFormatter())
HStack {
Text("Media inactivity timeout")
Spacer()
TextField("Media inactivity timeout", value: $vm.waitInterval, formatter: NumberFormatter())
.labelsHidden()
.frame(width: 25)
.multilineTextAlignment(.trailing)
Text("seconds")
.foregroundStyle(.secondary)
}
} header: {
Text("Media playback live activity")
}
Expand Down
4 changes: 4 additions & 0 deletions boringNotch/enums/generic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ public enum NotchViews {
case menu
case weather
}

enum SettingsEnum {
case general
}
16 changes: 12 additions & 4 deletions boringNotch/managers/MusicManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,22 @@ class MusicManager: ObservableObject {
}

if let artist = information["kMRMediaRemoteNowPlayingInfoArtist"] as? String {
self.artistName = artist
withAnimation {
self.artistName = artist
}
}

if let title = information["kMRMediaRemoteNowPlayingInfoTitle"] as? String {
self.songTitle = title
withAnimation {
self.songTitle = title
}
}

if let album = information["kMRMediaRemoteNowPlayingInfoAlbum"] as? String {
print("Album: \(album)")
self.album = album
withAnimation {
self.album = album
}
}

if let duration = information["kMRMediaRemoteNowPlayingInfoDuration"] as? String {
Expand All @@ -111,7 +117,9 @@ class MusicManager: ObservableObject {

if let artworkData = information["kMRMediaRemoteNowPlayingInfoArtworkData"] as? Data,
let artworkImage = NSImage(data: artworkData) {
self.albumArt = artworkImage
withAnimation {
self.albumArt = artworkImage
}
print("artworkData : \(artworkData)")
}

Expand Down
2 changes: 1 addition & 1 deletion boringNotch/models/BoringViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class BoringViewModel: NSObject, ObservableObject {
var cancellables: Set<AnyCancellable> = []

let animationLibrary:BoringAnimations = BoringAnimations()
let animation:Animation?
let animation: Animation?
@Published var contentType: ContentType = .normal
@Published var notchState: NotchState = .closed
@Published var currentView: NotchViews = .empty
Expand Down
6 changes: 3 additions & 3 deletions boringNotch/sizing/matters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ struct Sizes {
var corderRadius: StatesSizes = StatesSizes(opened: Area(inset: 24), closed: Area(inset:10))
var size: StatesSizes = StatesSizes(
opened:Area(width: 500, height: 220),
closed:Area(width: 320, height: 40)
closed:Area(width: 280, height: 42)
)
}

struct MusicPlayerElementSizes {
var image: Sizes = Sizes(
corderRadius: StatesSizes(
opened: Area(inset: 14), closed: Area(inset:4)),
size:StatesSizes(
opened: Area(width: 70, height: 70), closed: Area(width:20, height: 20)
size: StatesSizes(
opened: Area(width: 70, height: 70), closed: Area(width: 20, height: 20)
)
)
}