Commit 59438b4e authored by Azat Alimov's avatar Azat Alimov

Merge branch 'settings' into 'main'

#76: Port Settings from old codebase

See merge request !29
parents 1e4d279c f413d940
Pipeline #2749 failed with stage
......@@ -28,6 +28,7 @@
545A24AE2639ECAB00E0CC12 /* Authentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 545A24AD2639ECAA00E0CC12 /* Authentication.swift */; };
545A24B62639EE2F00E0CC12 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = 545A24B52639EE2F00E0CC12 /* Data.swift */; };
545FD29726205F1200F23F46 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 545FD29626205F1200F23F46 /* Dictionary.swift */; };
54663275267BDE56009D9B46 /* SettingsPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54663274267BDE56009D9B46 /* SettingsPane.swift */; };
54663245267B767F009D9B46 /* CustomRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54663244267B767F009D9B46 /* CustomRenderer.swift */; };
547780D5267A6545009DC45B /* PluginHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 547780D4267A6545009DC45B /* PluginHandler.swift */; };
5478EDD92641A3FC000EB938 /* ItemRecord+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5478EDD82641A3FC000EB938 /* ItemRecord+Sync.swift */; };
......@@ -262,6 +263,7 @@
545A24AD2639ECAA00E0CC12 /* Authentication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Authentication.swift; sourceTree = "<group>"; };
545A24B52639EE2F00E0CC12 /* Data.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = "<group>"; };
545FD29626205F1200F23F46 /* Dictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = "<group>"; };
54663274267BDE56009D9B46 /* SettingsPane.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsPane.swift; sourceTree = "<group>"; };
54663244267B767F009D9B46 /* CustomRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomRenderer.swift; sourceTree = "<group>"; };
547780D4267A6545009DC45B /* PluginHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginHandler.swift; sourceTree = "<group>"; };
5478EDD82641A3FC000EB938 /* ItemRecord+Sync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ItemRecord+Sync.swift"; sourceTree = "<group>"; };
......@@ -707,6 +709,7 @@
D79CA3A825CD0BCD0066D3AB /* RendererSettingsViews */,
D7E89CB425A80AE0003AEFD8 /* UIHelpers */,
541E88D6261B192A002BBC0B /* ContextPane.swift */,
54663274267BDE56009D9B46 /* SettingsPane.swift */,
);
path = UI;
sourceTree = "<group>";
......@@ -1504,6 +1507,7 @@
D7E998F825C524AF00401451 /* CVU_Other.swift in Sources */,
D7BEF0C725C2E3680043210E /* CVUValue_Constant.swift in Sources */,
D7E89C9B25A736DF003AEFD8 /* Threadly.swift in Sources */,
54663275267BDE56009D9B46 /* SettingsPane.swift in Sources */,
D78C75F625CA429800375790 /* GridRendererSettingsView.swift in Sources */,
54842CDC26372842000A66A7 /* FilterPanelSortItemView.swift in Sources */,
D7784F8425B70522004AB982 /* FileRenderer.swift in Sources */,
......
......@@ -8,14 +8,15 @@
import Foundation
import Alamofire
import Combine
import SwiftUI
struct PodAPIStandardRequest<Payload: Encodable> {
var method: HTTPMethod = .post
var path: String
var headers: HTTPHeaders = [:]
var payload: Payload
@AppStorage("/device/upload/cellular") var uploadOnCellular: Bool = false
func constructRequest(connectionConfig: PodAPIConnectionDetails) throws -> URLRequest {
var components = URLComponents()
components.scheme = connectionConfig.scheme
......@@ -31,6 +32,7 @@ struct PodAPIStandardRequest<Payload: Encodable> {
var request = URLRequest(url: url)
request.method = method
request.allowsCellularAccess = uploadOnCellular
switch method {
case .get:
......@@ -76,7 +78,8 @@ struct PodAPIUploadRequest<Payload: Encodable> {
var path: String
var fileURL: URL
var payload: Payload
@AppStorage("/device/upload/cellular") var uploadOnCellular: Bool = false
func constructRequest(connectionConfig: PodAPIConnectionDetails) throws -> URLRequest {
var components = URLComponents()
components.scheme = connectionConfig.scheme
......@@ -90,6 +93,8 @@ struct PodAPIUploadRequest<Payload: Encodable> {
var request = URLRequest(url: url)
request.method = .post
request.allowsCellularAccess = uploadOnCellular
if !(Payload.self == PodAPIPayload.EmptyPayload.self) {
request = try URLEncodedFormParameterEncoder().encode(payload, into: request)
}
......@@ -113,7 +118,8 @@ struct PodAPIDownloadRequest<Payload: Encodable> {
var method: HTTPMethod = .post
var payload: Payload
var fileUID: String
@AppStorage("/device/upload/cellular") var uploadOnCellular: Bool = false
var destination: DownloadRequest.Destination { { _, _ in
let fileURL = FileStorageController.getURLForFile(withUUID: fileUID)
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
......@@ -135,7 +141,8 @@ struct PodAPIDownloadRequest<Payload: Encodable> {
var request = URLRequest(url: url)
request.method = method
request.allowsCellularAccess = uploadOnCellular
switch method {
case .get:
/// For a `get` request, encode our payload into the URL.
......
......@@ -8,10 +8,12 @@
import Foundation
import KeychainAccess
import Combine
import SwiftUI
class AppController: ObservableObject {
static let shared = AppController()
@AppStorage("/user/pod/host") var podURL: String = "http://localhost:3030"
let databaseController: DatabaseController
let syncController: SyncController
let cvuController: CVUController
......@@ -89,13 +91,40 @@ class AppController: ObservableObject {
onCompletion(nil)
}
private var podScheme: String {
guard let url = URL(string: podURL),
let scheme = url.scheme else {
return "http"
}
return scheme
}
private var podHost: String {
guard let url = URL(string: podURL),
let host = url.host else {
return "localhost"
}
return host
}
private var podPort: Int {
guard let url = URL(string: podURL),
let port = url.port else {
return 3030
}
return port
}
// MARK: Pod connection
var podConnectionConfig: PodAPIConnectionDetails? {
do {
return try databaseController.read { db in
// Here you should retrieve the connection details stored in the database
let keys = try ItemRecord.getOwnerAndDBKey()
return PodAPIConnectionDetails(keys: keys)
return PodAPIConnectionDetails(scheme: podScheme, host: podHost, port: podPort, keys: keys)
}
} catch {
print(error)
......
......@@ -33,12 +33,19 @@ extension Date {
return String(format: formatString, timeString)
}
func formatted(_ dateFormat: String = "yyyy/MM/dd HH:mm") -> String {
func formatted(_ dateFormat: String? = nil) -> String {
let showTimeAgo = UserDefaults.standard.bool(forKey: "/user/general/gui/showDateAgo")
guard showTimeAgo == false else {
return self.timestampString ?? ""
}
let format = dateFormat ?? UserDefaults.standard.string(forKey: "/user/formatting/date") ?? "yyyy/MM/dd HH:mm"
// Compare against 36 hours ago
if self.timeIntervalSince(Date(timeIntervalSinceNow: -129_600)) < 0
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
dateFormatter.dateFormat = format
dateFormatter.locale = Locale(identifier: "en_US")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
return dateFormatter.string(from: self)
......
......@@ -8,6 +8,7 @@ import SwiftUI
struct TopBarView: View {
@ObservedObject
var sceneController: SceneController
@AppStorage("/user/general/gui/showEditButton") var showEditButton: Bool = true
@ViewBuilder
......@@ -46,7 +47,8 @@ struct TopBarView: View {
}
HStack {
if let context = sceneController.topMostContext,
let editAction = sceneController.topMostContext?.viewDefinitionPropertyResolver.stringArray("editActionButton").first
let editAction = sceneController.topMostContext?.viewDefinitionPropertyResolver.stringArray("editActionButton").first,
showEditButton
{
if let action = cvuAction(named: editAction) {
ActionButton(action: action.init(vars: ["icon": .constant(.string("pencil"))]), context: context.getCVUContext())
......
......@@ -23,9 +23,9 @@ struct NavigationPaneView: View {
.font(Font.system(size: 22, weight: .semibold))
.foregroundColor(Color(hex: "#d9d2e9"))
}
// .sheet(isPresented: self.$showSettings) {
// SettingsPane().environmentObject(self.context)
// }
.sheet(isPresented: self.$showSettings) {
SettingsPane()
}
MemriTextField(
value: $sceneController.navigationFilterText,
......
......@@ -10,7 +10,7 @@ import SwiftUI
struct TimelineRendererView: View {
@EnvironmentObject var sceneController: SceneController
@ObservedObject var viewContext: ViewContextController
@AppStorage("/user/general/gui/showDateAgo") var showTimeAgo: Bool = false
func generateModel() -> TimelineRendererModel {
TimelineRendererModel(
......@@ -203,6 +203,10 @@ extension TimelineRendererView {
}()
let largeString: String? = {
guard showTimeAgo == false else {
return group.date.timestampString ?? ""
}
switch model.detailLevel {
case .hour:
if group.isStartOf.contains(.day) {
......@@ -231,6 +235,10 @@ extension TimelineRendererView {
}()
let smallString: String? = {
guard showTimeAgo == false else {
return group.date.timestampString ?? ""
}
switch model.detailLevel {
case .hour:
let format = DateFormatter()
......
//
// SettingsPane.swift
// Memri
//
import Foundation
import SwiftUI
struct SettingsPane: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@AppStorage("/device/upload/cellular") var uploadOnCellular: Bool = false
@AppStorage("/device/sensors/location/track") var locationTracking: Bool = false
@AppStorage("/user/pod/host") var podURL: String = "http://localhost:3030"
@AppStorage("/user/formatting/date") var dateFormat: String = "yyyy/MM/dd HH:mm"
@AppStorage("/user/general/gui/showEditButton") var showEditButton: Bool = true
@AppStorage("/user/general/gui/showDateAgo") var showTimeAgo: Bool = false
@AppStorage("/device/debug/autoShowErrorConsole") var autoShowErrorConsole: Bool = false
@AppStorage("/device/debug/autoReloadCVU") var autoReloadCVU: Bool = true
// .keyboardType(.numberPad)
var body: some View {
NavigationView {
Form {
NavigationLink(destination: Form {
Section(
header: Text("Pod Connection"),
footer: Text("Never give out these details to anyone")
.font(.system(size: 11, weight: .regular))
) {
HStack {
Text("Host:")
.frame(width: 100, alignment: .leading)
MemriTextField(value: $podURL)
}
HStack {
Button(action: {
try? AppController.shared.syncController.sync()
}) {
Text("Connect")
}
}
}
Section(
header: Text("Syncing")
) {
Toggle(isOn: $uploadOnCellular) {
Text("Enable upload of images while on cellular")
}
}
}) {
Text("Pod Connection")
}
NavigationLink(destination: Form {
Section(
header: Text("User Interface"),
footer: Text("Show 'xx time ago' in place of dates less than 36 hours ago")
.font(.system(size: 11, weight: .regular))
) {
Toggle(isOn: $showEditButton) {
Text("Always show edit button")
}
Toggle(isOn: $showTimeAgo) {
Text("Enable time ago")
}
}
}) {
Text("User Interface")
}
NavigationLink(destination: Form {
Section(
header: Text("Sensors")
) {
Toggle(isOn: $locationTracking) {
Text("Track and store location")
}
}
}) {
Text("Sensors")
}
NavigationLink(destination: Form {
Section(header: Text("Internationalization")) {
MemriTextField(
value: $dateFormat
)
}
}) {
Text("Internationalization")
}
NavigationLink(destination: Form {
Section(
header: Text("Debug Settings")
) {
Toggle(isOn: $autoShowErrorConsole) {
Text("Automatically pop up the debug console on errors")
}
Toggle(isOn: $autoReloadCVU) {
Text("Automatically reload CVU when it changes")
}
}
Section(
header: Text("Debug Actions")
) {
HStack {
Button(action: {
try? AppController.shared.syncController.sync()
}) {
Text("Sync To Pod")
}
}
}
}) {
Text("Debug")
}
}
.navigationBarItems(leading:
Button(action: { self.presentationMode.wrappedValue.dismiss() }) {
Text("Close")
})
.navigationBarTitle(Text("Settings"), displayMode: .inline)
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment