summaryrefslogtreecommitdiff
path: root/Jel/Models
diff options
context:
space:
mode:
Diffstat (limited to 'Jel/Models')
-rw-r--r--Jel/Models/BlurHashDecode.swift153
-rw-r--r--Jel/Models/JellyfinDateFormatter.swift33
-rw-r--r--Jel/Models/JellyfinKitExtensions.swift28
-rw-r--r--Jel/Models/UIScreenWidthExtension.swift15
-rw-r--r--Jel/Models/ViewExtensions.swift31
5 files changed, 0 insertions, 260 deletions
diff --git a/Jel/Models/BlurHashDecode.swift b/Jel/Models/BlurHashDecode.swift
deleted file mode 100644
index 93c4896..0000000
--- a/Jel/Models/BlurHashDecode.swift
+++ /dev/null
@@ -1,153 +0,0 @@
-//
-// BlurHashDecode.swift
-// Jel
-//
-// Created by zerocool on 12/22/23.
-//
-
-import UIKit
-
-extension UIImage {
- public convenience init?(blurHash: String, size: CGSize, punch: Float = 1) {
- guard blurHash.count >= 6 else { return nil }
-
- let sizeFlag = String(blurHash[0]).decode83()
- let numY = (sizeFlag / 9) + 1
- let numX = (sizeFlag % 9) + 1
-
- let quantisedMaximumValue = String(blurHash[1]).decode83()
- let maximumValue = Float(quantisedMaximumValue + 1) / 166
-
- guard blurHash.count == 4 + 2 * numX * numY else { return nil }
-
- let colours: [(Float, Float, Float)] = (0 ..< numX * numY).map { i in
- if i == 0 {
- let value = String(blurHash[2 ..< 6]).decode83()
- return decodeDC(value)
- } else {
- let value = String(blurHash[4 + i * 2 ..< 4 + i * 2 + 2]).decode83()
- return decodeAC(value, maximumValue: maximumValue * punch)
- }
- }
-
- let width = Int(size.width)
- let height = Int(size.height)
- let bytesPerRow = width * 3
- guard let data = CFDataCreateMutable(kCFAllocatorDefault, bytesPerRow * height) else { return nil }
- CFDataSetLength(data, bytesPerRow * height)
- guard let pixels = CFDataGetMutableBytePtr(data) else { return nil }
-
- for y in 0 ..< height {
- for x in 0 ..< width {
- var r: Float = 0
- var g: Float = 0
- var b: Float = 0
-
- for j in 0 ..< numY {
- for i in 0 ..< numX {
- let basis = cos(Float.pi * Float(x) * Float(i) / Float(width)) * cos(Float.pi * Float(y) * Float(j) / Float(height))
- let colour = colours[i + j * numX]
- r += colour.0 * basis
- g += colour.1 * basis
- b += colour.2 * basis
- }
- }
-
- let intR = UInt8(linearTosRGB(r))
- let intG = UInt8(linearTosRGB(g))
- let intB = UInt8(linearTosRGB(b))
-
- pixels[3 * x + 0 + y * bytesPerRow] = intR
- pixels[3 * x + 1 + y * bytesPerRow] = intG
- pixels[3 * x + 2 + y * bytesPerRow] = intB
- }
- }
-
- let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue)
-
- guard let provider = CGDataProvider(data: data) else { return nil }
- guard let cgImage = CGImage(width: width, height: height, bitsPerComponent: 8, bitsPerPixel: 24, bytesPerRow: bytesPerRow,
- space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: true, intent: .defaultIntent) else { return nil }
-
- self.init(cgImage: cgImage)
- }
-}
-
-private func decodeDC(_ value: Int) -> (Float, Float, Float) {
- let intR = value >> 16
- let intG = (value >> 8) & 255
- let intB = value & 255
- return (sRGBToLinear(intR), sRGBToLinear(intG), sRGBToLinear(intB))
-}
-
-private func decodeAC(_ value: Int, maximumValue: Float) -> (Float, Float, Float) {
- let quantR = value / (19 * 19)
- let quantG = (value / 19) % 19
- let quantB = value % 19
-
- let rgb = (
- signPow((Float(quantR) - 9) / 9, 2) * maximumValue,
- signPow((Float(quantG) - 9) / 9, 2) * maximumValue,
- signPow((Float(quantB) - 9) / 9, 2) * maximumValue
- )
-
- return rgb
-}
-
-private func signPow(_ value: Float, _ exp: Float) -> Float {
- return copysign(pow(abs(value), exp), value)
-}
-
-private func linearTosRGB(_ value: Float) -> Int {
- let v = max(0, min(1, value))
- if v <= 0.0031308 { return Int(v * 12.92 * 255 + 0.5) }
- else { return Int((1.055 * pow(v, 1 / 2.4) - 0.055) * 255 + 0.5) }
-}
-
-private func sRGBToLinear<Type: BinaryInteger>(_ value: Type) -> Float {
- let v = Float(Int64(value)) / 255
- if v <= 0.04045 { return v / 12.92 }
- else { return pow((v + 0.055) / 1.055, 2.4) }
-}
-
-private let encodeCharacters: [String] = {
- return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".map { String($0) }
-}()
-
-private let decodeCharacters: [String: Int] = {
- var dict: [String: Int] = [:]
- for (index, character) in encodeCharacters.enumerated() {
- dict[character] = index
- }
- return dict
-}()
-
-extension String {
- func decode83() -> Int {
- var value: Int = 0
- for character in self {
- if let digit = decodeCharacters[String(character)] {
- value = value * 83 + digit
- }
- }
- return value
- }
-}
-
-private extension String {
- subscript (offset: Int) -> Character {
- return self[index(startIndex, offsetBy: offset)]
- }
-
- subscript (bounds: CountableClosedRange<Int>) -> Substring {
- let start = index(startIndex, offsetBy: bounds.lowerBound)
- let end = index(startIndex, offsetBy: bounds.upperBound)
- return self[start...end]
- }
-
- subscript (bounds: CountableRange<Int>) -> Substring {
- let start = index(startIndex, offsetBy: bounds.lowerBound)
- let end = index(startIndex, offsetBy: bounds.upperBound)
- return self[start..<end]
- }
-}
diff --git a/Jel/Models/JellyfinDateFormatter.swift b/Jel/Models/JellyfinDateFormatter.swift
deleted file mode 100644
index 74b89d1..0000000
--- a/Jel/Models/JellyfinDateFormatter.swift
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// JellyfinDateFormatter.swift
-// Jel
-//
-// Created by zerocool on 12/12/23.
-//
-
-import Foundation
-
-// from: https://stackoverflow.com/a/46458771
-extension Formatter {
- static let iso8601withFractionalSeconds: ISO8601DateFormatter = {
- let formatter = ISO8601DateFormatter()
- formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
- return formatter
- }()
- static let iso8601: ISO8601DateFormatter = {
- let formatter = ISO8601DateFormatter()
- formatter.formatOptions = [.withInternetDateTime]
- return formatter
- }()
-}
-
-extension JSONDecoder.DateDecodingStrategy {
- static let iso8601withFractionalSeconds = custom {
- let container = try $0.singleValueContainer()
- let string = try container.decode(String.self)
- if let date = Formatter.iso8601withFractionalSeconds.date(from: string) ?? Formatter.iso8601.date(from: string) {
- return date
- }
- throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: \(string)")
- }
-}
diff --git a/Jel/Models/JellyfinKitExtensions.swift b/Jel/Models/JellyfinKitExtensions.swift
deleted file mode 100644
index 197731c..0000000
--- a/Jel/Models/JellyfinKitExtensions.swift
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// JellyfinKitExtensions.swift
-// Jel
-//
-// Created by zerocool on 12/24/23.
-//
-
-import Foundation
-import JellyfinKit
-
-extension BaseItemDto {
- func getRuntime() -> String? {
- let formatter: DateComponentsFormatter = {
- let localFormatter = DateComponentsFormatter()
- localFormatter.unitsStyle = .brief
- localFormatter.allowedUnits = [.hour, .minute]
-
- return localFormatter
- }()
-
- if let runTimeTicks = self.runTimeTicks {
- let text = formatter.string(from: Double(runTimeTicks / 10_000_000))
- return text
- }
-
- return nil
- }
-}
diff --git a/Jel/Models/UIScreenWidthExtension.swift b/Jel/Models/UIScreenWidthExtension.swift
deleted file mode 100644
index 6f2f5de..0000000
--- a/Jel/Models/UIScreenWidthExtension.swift
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// UIScreenWidthExtension.swift
-// Jel
-//
-// Created by zerocool on 2/14/24.
-//
-
-import Foundation
-import UIKit
-
-extension UIScreen{
- static let screenWidth = UIScreen.main.bounds.size.width
- static let screenHeight = UIScreen.main.bounds.size.height
- static let screenSize = UIScreen.main.bounds.size
-}
diff --git a/Jel/Models/ViewExtensions.swift b/Jel/Models/ViewExtensions.swift
deleted file mode 100644
index 7f54865..0000000
--- a/Jel/Models/ViewExtensions.swift
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// ViewExtensions.swift
-// Jel
-//
-// Created by zerocool on 12/25/23.
-//
-
-import SwiftUI
-
-extension View {
- /// Applies the given transform if the given condition evaluates to `true`.
- @ViewBuilder func `if`<Content: View>(_ condition: @autoclosure () -> Bool, transform: (Self) -> Content) -> some View {
- if condition() {
- transform(self)
- } else {
- self
- }
- }
-}
-
-extension View {
- /// Applies an inverse mask to the given view
- public func inverseMask<Content: View>(_ mask: Content) -> some View {
- let inverseMask = mask
- .foregroundStyle(.black)
- .background(.white)
- .compositingGroup()
- .luminanceToAlpha()
- return self.mask(inverseMask)
- }
-}