From 01ce93653d86f2a47eda58d2e74c3926981b22cf Mon Sep 17 00:00:00 2001 From: Christian Segundo Date: Mon, 24 Jul 2023 10:45:15 +0200 Subject: wip --- Xmission/Code/Home/Actions/AddTorrent.swift | 8 ++ Xmission/Code/Home/Actions/DeleteTorrent.swift | 8 ++ Xmission/Code/Home/Actions/LoginAction.swift | 52 +++++++++++++ .../Code/Home/Models/ListTorrentResponse.swift | 12 +++ Xmission/Code/Home/Models/LoginRequest.swift | 6 ++ Xmission/Code/Home/Models/LoginResponse.swift | 10 +++ Xmission/Code/Home/Screens/HomeScreen.swift | 89 ++++++++++++++++++++++ Xmission/Code/Home/ViewModels/HomeViewModel.swift | 35 +++++++++ .../Utilities/Extensions/StringExtensions.swift | 11 +++ 9 files changed, 231 insertions(+) create mode 100644 Xmission/Code/Home/Actions/AddTorrent.swift create mode 100644 Xmission/Code/Home/Actions/DeleteTorrent.swift create mode 100644 Xmission/Code/Home/Actions/LoginAction.swift create mode 100644 Xmission/Code/Home/Models/ListTorrentResponse.swift create mode 100644 Xmission/Code/Home/Models/LoginRequest.swift create mode 100644 Xmission/Code/Home/Models/LoginResponse.swift create mode 100644 Xmission/Code/Home/Screens/HomeScreen.swift create mode 100644 Xmission/Code/Home/ViewModels/HomeViewModel.swift create mode 100644 Xmission/Code/Utilities/Extensions/StringExtensions.swift (limited to 'Xmission/Code') diff --git a/Xmission/Code/Home/Actions/AddTorrent.swift b/Xmission/Code/Home/Actions/AddTorrent.swift new file mode 100644 index 0000000..70dae56 --- /dev/null +++ b/Xmission/Code/Home/Actions/AddTorrent.swift @@ -0,0 +1,8 @@ +// +// AddTorrent.swift +// Xmission +// +// Created by Christian Segundo Guevara on 22/7/23. +// + +import Foundation diff --git a/Xmission/Code/Home/Actions/DeleteTorrent.swift b/Xmission/Code/Home/Actions/DeleteTorrent.swift new file mode 100644 index 0000000..5fcf494 --- /dev/null +++ b/Xmission/Code/Home/Actions/DeleteTorrent.swift @@ -0,0 +1,8 @@ +// +// DeleteTorrent.swift +// Xmission +// +// Created by Christian Segundo Guevara on 22/7/23. +// + +import Foundation diff --git a/Xmission/Code/Home/Actions/LoginAction.swift b/Xmission/Code/Home/Actions/LoginAction.swift new file mode 100644 index 0000000..81fa97c --- /dev/null +++ b/Xmission/Code/Home/Actions/LoginAction.swift @@ -0,0 +1,52 @@ +import Foundation + +struct LoginAction { + + var parameters: LoginRequest + + func call(completion: @escaping (LoginResponse) -> Void) { + + let scheme: String = "https" + let host: String = "base_url" + let path = "/login" + + var components = URLComponents() + components.scheme = scheme + components.host = host + components.path = path + + guard let url = components.url else { + return + } + + var request = URLRequest(url: url) + request.httpMethod = "post" + + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + request.addValue("application/json", forHTTPHeaderField: "Accept") + + do { + request.httpBody = try JSONEncoder().encode(parameters) + } catch { + // Error: Unable to encode request parameters + } + + let task = URLSession.shared.dataTask(with: request) { data, _, error in + if let data = data { + let response = try? JSONDecoder().decode(LoginResponse.self, from: data) + + if let response = response { + completion(response) + } else { + // Error: Unable to decode response JSON + } + } else { + // Error: API request failed + if let error = error { + print("Error: \(error.localizedDescription)") + } + } + } + task.resume() + } +} diff --git a/Xmission/Code/Home/Models/ListTorrentResponse.swift b/Xmission/Code/Home/Models/ListTorrentResponse.swift new file mode 100644 index 0000000..42331cd --- /dev/null +++ b/Xmission/Code/Home/Models/ListTorrentResponse.swift @@ -0,0 +1,12 @@ +import Foundation + +typealias ListTorrentResponse = [Torrent] + +struct Torrent: Decodable { + var name: String + var completionPercent: Float + let ratio: Float + let rateDownload: Int64 + let rateUpload: Int64 + let labels: [String] +} diff --git a/Xmission/Code/Home/Models/LoginRequest.swift b/Xmission/Code/Home/Models/LoginRequest.swift new file mode 100644 index 0000000..40ef3f6 --- /dev/null +++ b/Xmission/Code/Home/Models/LoginRequest.swift @@ -0,0 +1,6 @@ +import Foundation + +struct LoginRequest: Encodable { + let username: String + let password: String +} diff --git a/Xmission/Code/Home/Models/LoginResponse.swift b/Xmission/Code/Home/Models/LoginResponse.swift new file mode 100644 index 0000000..51bd864 --- /dev/null +++ b/Xmission/Code/Home/Models/LoginResponse.swift @@ -0,0 +1,10 @@ +import Foundation + +struct LoginResponse: Decodable { + let data: LoginResponseData +} + +struct LoginResponseData: Decodable { + let accessToken: String + let refreshToken: String +} diff --git a/Xmission/Code/Home/Screens/HomeScreen.swift b/Xmission/Code/Home/Screens/HomeScreen.swift new file mode 100644 index 0000000..dac8a20 --- /dev/null +++ b/Xmission/Code/Home/Screens/HomeScreen.swift @@ -0,0 +1,89 @@ +import SwiftUI + +struct HomeScreen: View { + @ObservedObject var viewModel: HomeViewModel = .init() + + var body: some View { + NavigationView { + List { + ForEach(viewModel.torrents, id: \.name) { torrent in + TorrentRow(torrent: torrent) + .swipeActions(edge: .trailing) { + Button {} label: { + Label("Delete", systemImage: "trash") + } + .tint(.red) + } + .listRowSeparator(.hidden) + } + } + .listStyle(.plain) + + .navigationBarTitle(Text("192.168.0.2"), displayMode: .inline) + .navigationBarItems( + leading: Button( + action: { print("Adding torrent") }, + label: { Image(systemName: "plus") } + ), + trailing: + Button( + action: { print("Going to Settings") }, + label: { Image(systemName: "gear") } + ) + ) + } + } +} + +struct TorrentRow: View { + let torrent: Torrent + + var body: some View { + HStack { + ProgressView( + value: torrent.completionPercent, + total: 100, + label: { + VStack { + Text(torrent.name) + HStack { + // todo chips + } + } + }, + currentValueLabel: { + HStack { + Text("Ratio: " + String(torrent.ratio)).frame( + maxWidth: .infinity, + maxHeight: .infinity, + alignment: .leading + ) + + Text(String(torrent.completionPercent) + "%").frame( + maxWidth: .infinity, + maxHeight: .infinity, + alignment: .center + ) + + HStack { + Image(systemName: "chevron.up", variableValue: 100) + Text(String(torrent.rateUpload)) + Image(systemName: "chevron.down") + Text(String(torrent.rateDownload)) + }.frame( + maxWidth: .infinity, + maxHeight: .infinity, + alignment: .trailing + ) + } + } + ) + } + } +} + +struct HomeScreen_Previews: PreviewProvider { + static var previews: some View { + HomeScreen() + } +} diff --git a/Xmission/Code/Home/ViewModels/HomeViewModel.swift b/Xmission/Code/Home/ViewModels/HomeViewModel.swift new file mode 100644 index 0000000..f1b95e5 --- /dev/null +++ b/Xmission/Code/Home/ViewModels/HomeViewModel.swift @@ -0,0 +1,35 @@ +import Foundation + +class HomeViewModel: ObservableObject { + @Published var torrents: ListTorrentResponse = [] + + var timer: Timer? + + init() { + timer = Timer.scheduledTimer( + withTimeInterval: 1, + repeats: true, + block: { _ in + self.refresh() + } + ) + } + + deinit { + timer?.invalidate() + } + + func refresh() { + let randomFloat = Float.random(in: 1 ..< 100) + + torrents = [ + Torrent( + name: "foo", + completionPercent: randomFloat, ratio: 0, + rateDownload: 1, + rateUpload: 1, + labels: ["foo", "bar"] + ) + ] + } +} diff --git a/Xmission/Code/Utilities/Extensions/StringExtensions.swift b/Xmission/Code/Utilities/Extensions/StringExtensions.swift new file mode 100644 index 0000000..5e7455d --- /dev/null +++ b/Xmission/Code/Utilities/Extensions/StringExtensions.swift @@ -0,0 +1,11 @@ +import Foundation + +extension String { + var localized: String { + return NSLocalizedString(self, comment: "") + } + + func localized(arguments: CVarArg...) -> String { + return String(format: localized, arguments: arguments) + } +} -- cgit v1.2.3