Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import SwiftUI

public extension Color {

func idealTextColor() -> Color {
guard let components = UIColor(self).cgColor.components else {
return .black
}

let red = Double(components[0])
let green = Double(components[1])
let blue = Double(components[2])

let brightness =
(red * 299) +
(green * 587) +
(blue * 114)

return brightness < 0.6 ? .white : .black
}
}

public extension UIColor {
var perceivedBrightness: CGFloat {
var redComponent: CGFloat = 0
var greenComponent: CGFloat = 0
var blueComponent: CGFloat = 0
var alphaComponent: CGFloat = 0

guard getRed(&redComponent, green: &greenComponent, blue: &blueComponent, alpha: &alphaComponent) else {
return 0.5
}

let brightness =
(redComponent * 299) +
(greenComponent * 587) +
(blueComponent * 114)

return brightness / 1000
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import UIKit

public extension UIImage {

func averageColor() -> UIColor? {
guard let cgImage = cgImage else { return nil }

let targetSize = CGSize(width: 1, height: 1)
let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue

guard let context = CGContext(
data: nil,
width: Int(targetSize.width),
height: Int(targetSize.height),
bitsPerComponent: 8,
bytesPerRow: Int(targetSize.width) * 4,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: bitmapInfo
) else {
return nil
}

context.interpolationQuality = .medium
context.draw(cgImage, in: CGRect(origin: .zero, size: targetSize))

guard let pixelBuffer = context.data else { return nil }

let pixelPointer = pixelBuffer.bindMemory(to: UInt8.self, capacity: 4)

let redComponent = CGFloat(pixelPointer[0]) / 255.0
let greenComponent = CGFloat(pixelPointer[1]) / 255.0
let blueComponent = CGFloat(pixelPointer[2]) / 255.0
let alphaComponent = CGFloat(pixelPointer[3]) / 255.0

return UIColor(
red: redComponent,
green: greenComponent,
blue: blueComponent,
alpha: alphaComponent
)
}

func twoToneGradientColors() -> (UIColor, UIColor)? {
guard let averageColor = averageColor() else { return nil }

var hueValue: CGFloat = 0
var saturationValue: CGFloat = 0
var brightnessValue: CGFloat = 0
var alphaValue: CGFloat = 0

guard averageColor.getHue(
&hueValue,
saturation: &saturationValue,
brightness: &brightnessValue,
alpha: &alphaValue
) else {
return (averageColor, averageColor)
}

let lighterTopColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 0.9, 0.2), 1.0),
brightness: min(brightnessValue * 1.2, 1.0),
alpha: 1.0
)

let darkerBottomColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 1.1, 0.25), 1.0),
brightness: max(brightnessValue * 0.5, 0.1),
alpha: 1.0
)

return (lighterTopColor, darkerBottomColor)
}

func threeToneGradientColors() -> [UIColor]? {
guard let averageColor = averageColor() else { return nil }

var hueValue: CGFloat = 0
var saturationValue: CGFloat = 0
var brightnessValue: CGFloat = 0
var alphaValue: CGFloat = 0

guard averageColor.getHue(
&hueValue,
saturation: &saturationValue,
brightness: &brightnessValue,
alpha: &alphaValue
) else {
return [averageColor, averageColor, averageColor]
}

let topColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 0.85, 0.18), 1.0),
brightness: min(brightnessValue * 1.25, 1.0),
alpha: 1.0
)

let middleColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 1.0, 0.22), 1.0),
brightness: min(max(brightnessValue * 0.95, 0.15), 1.0),
alpha: 1.0
)

let bottomColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 1.15, 0.28), 1.0),
brightness: max(brightnessValue * 0.45, 0.08),
alpha: 1.0
)

return [topColor, middleColor, bottomColor]
}

func fourToneGradientColors() -> [UIColor]? {
guard let averageColor = averageColor() else { return nil }

var hueValue: CGFloat = 0
var saturationValue: CGFloat = 0
var brightnessValue: CGFloat = 0
var alphaValue: CGFloat = 0

guard averageColor.getHue(
&hueValue,
saturation: &saturationValue,
brightness: &brightnessValue,
alpha: &alphaValue
) else {
return [averageColor, averageColor, averageColor, averageColor]
}

let topColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 0.8, 0.18), 1.0),
brightness: min(brightnessValue * 1.25, 1.0),
alpha: 1.0
)

let upperMiddleColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 0.95, 0.20), 1.0),
brightness: min(max(brightnessValue * 1.05, 0.18), 1.0),
alpha: 1.0
)

let lowerMiddleColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 1.1, 0.24), 1.0),
brightness: max(brightnessValue * 0.75, 0.12),
alpha: 1.0
)

let bottomColor = UIColor(
hue: hueValue,
saturation: min(max(saturationValue * 1.2, 0.30), 1.0),
brightness: max(brightnessValue * 0.45, 0.08),
alpha: 1.0
)

return [topColor, upperMiddleColor, lowerMiddleColor, bottomColor]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ import Combine
import FeedLibrary
import Foundation
import MediaPlayer
import Observation
import UIKit

@MainActor
@Observable
class PodcastPlayerManager {
var currentPodcast: PodcastDB?
var isPlaying: Bool = false
var currentTime: TimeInterval = 0
var duration: TimeInterval = 0
var playbackRate: Float = 1.0
public class PodcastPlayerManager {
public var currentPodcast: PodcastDB?
public var isPlaying: Bool = false
public var currentTime: TimeInterval = 0
public var duration: TimeInterval = 0
public var playbackRate: Float = 1.0

private var player: AVPlayer?
private var timeObserver: Any?
private var cancellables = Set<AnyCancellable>()
private var isAudioSessionSetup = false
private var isRemoteControlsSetup = false

init() {
}
public init() {}

private func setupAudioSession() {
guard !isAudioSessionSetup else { return }
Expand Down Expand Up @@ -156,13 +156,13 @@ class PodcastPlayerManager {
updateNowPlayingInfo()
}

func pause() {
public func pause() {
player?.pause()
isPlaying = false
updateNowPlayingInfo()
}

func togglePlayPause() {
public func togglePlayPause() {
if isPlaying {
pause()
} else {
Expand Down
Loading