Skip to content
GitLab
Explore
Projects
Groups
Snippets
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Memri
iOS application
Commits
d624dc04
Commit
d624dc04
authored
4 years ago
by
Ruben Daniels
Browse files
Options
Download
Email Patches
Plain Diff
Add setting to toggle CVU listener
parent
0bab175f
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
memri.xcodeproj/project.pbxproj
+4
-0
memri.xcodeproj/project.pbxproj
memri/cvu/defaults/type/AuditItem.cvu
+2
-2
memri/cvu/defaults/type/AuditItem.cvu
memri/cvu/views/ViewDebugger.swift
+0
-4
memri/cvu/views/ViewDebugger.swift
memri/cvu/views/Views.swift
+19
-5
memri/cvu/views/Views.swift
memri/gui/SettingsPane.swift
+4
-15
memri/gui/SettingsPane.swift
memri/model/Cache.swift
+11
-1
memri/model/Cache.swift
memri/model/CachePubSub.swift
+1
-1
memri/model/CachePubSub.swift
memri/model/Settings.swift
+40
-3
memri/model/Settings.swift
memri/model/SettingsPubSub.swift
+77
-0
memri/model/SettingsPubSub.swift
memri/model/Sync.swift
+1
-1
memri/model/Sync.swift
memri/model/defaults/default_database.json
+1
-0
memri/model/defaults/default_database.json
with
160 additions
and
32 deletions
+160
-32
memri.xcodeproj/project.pbxproj
+
4
-
0
View file @
d624dc04
...
...
@@ -158,6 +158,7 @@
866F87EC24572525000E5FAB
/* ThumbGridRendererView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
866F87EB24572525000E5FAB
/* ThumbGridRendererView.swift */
;
};
8672C27C2497F35A006F0D42
/* CustomRenderer.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
8672C27B2497F35A006F0D42
/* CustomRenderer.swift */
;
};
867527BA24B76F5B002B5006
/* CachePubSub.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
867527B924B76F5B002B5006
/* CachePubSub.swift */
;
};
867527BC24B8290B002B5006
/* SettingsPubSub.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
867527BB24B8290B002B5006
/* SettingsPubSub.swift */
;
};
86865D3324487B390010271A
/* SettingsPane.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
86865D3224487B390010271A
/* SettingsPane.swift */
;
};
86865D36244996900010271A
/* styles.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
86865D35244996900010271A
/* styles.swift */
;
};
86865D38244996AA0010271A
/* FlowStack.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
86865D37244996AA0010271A
/* FlowStack.swift */
;
};
...
...
@@ -414,6 +415,7 @@
866F87EB24572525000E5FAB
/* ThumbGridRendererView.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ThumbGridRendererView.swift
;
sourceTree
=
"<group>"
;
};
8672C27B2497F35A006F0D42
/* CustomRenderer.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
CustomRenderer.swift
;
sourceTree
=
"<group>"
;
};
867527B924B76F5B002B5006
/* CachePubSub.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
CachePubSub.swift
;
sourceTree
=
"<group>"
;
};
867527BB24B8290B002B5006
/* SettingsPubSub.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingsPubSub.swift
;
sourceTree
=
"<group>"
;
};
86865D3224487B390010271A
/* SettingsPane.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingsPane.swift
;
sourceTree
=
"<group>"
;
wrapsLines
=
0
;
};
86865D35244996900010271A
/* styles.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
styles.swift
;
sourceTree
=
"<group>"
;
};
86865D37244996AA0010271A
/* FlowStack.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
FlowStack.swift
;
sourceTree
=
"<group>"
;
};
...
...
@@ -914,6 +916,7 @@
861C52C124A5A9B100B3230C
/* schema.swift */
,
8665ADD8241A8387005B3FA5
/* Cache.swift */
,
867527B924B76F5B002B5006
/* CachePubSub.swift */
,
867527BB24B8290B002B5006
/* SettingsPubSub.swift */
,
868EF696247784C600C0375F
/* ResultSet.swift */
,
86A5D8392437321700F8FAD8
/* Sync.swift */
,
5D78D071242531BE00F7BD3B
/* MainNavigation.swift */
,
...
...
@@ -1566,6 +1569,7 @@
8690AF022472D8C300FC49F4
/* view.swift in Sources */
,
868EF659247678BC00C0375F
/* Colors.swift in Sources */
,
5D301F62245C372400183BD2
/* ListRendererView.swift in Sources */
,
867527BC24B8290B002B5006
/* SettingsPubSub.swift in Sources */
,
86C3A73524518763006D4F55
/* ItemCell.swift in Sources */
,
B81237ED24A43E42003E8BCB
/* MapHelper.swift in Sources */
,
868EF6992477960D00C0375F
/* HashableClass.swift in Sources */
,
...
...
This diff is collapsed.
Click to expand it.
memri/cvu/defaults/type/AuditItem.cvu
+
2
-
2
View file @
d624dc04
...
...
@@ -37,13 +37,13 @@ AuditItem[] {
}
Spacer
Text {
text: "{.date}"
text: "{.date
Created
}"
font: 11 regular
color: #888
}
}
Text {
text: "{.content
s
}"
text: "{.content}"
font: 14 light
removeWhiteSpace: true
maxChar: 100
...
...
This diff is collapsed.
Click to expand it.
memri/cvu/views/ViewDebugger.swift
+
0
-
4
View file @
d624dc04
...
...
@@ -134,10 +134,6 @@ class DebugHistory: ObservableObject {
))
}
if
Settings
.
get
(
"device/debug/autoShowErrorConsole"
)
??
false
{
showErrorConsole
=
true
}
print
(
"
\(
time
()
)
WARNING:
\(
message
.
replace
(
"
\n
"
,
"
\n
"
)
)
"
)
}
...
...
This diff is collapsed.
Click to expand it.
memri/cvu/views/Views.swift
+
19
-
5
View file @
d624dc04
...
...
@@ -12,7 +12,8 @@ public class Views {
private
var
recursionCounter
=
0
private
var
realm
:
Realm
private
var
cancellable
:
AnyCancellable
?
private
var
CVUWatcher
:
AnyCancellable
?
=
nil
private
var
settingWatcher
:
AnyCancellable
?
=
nil
init
(
_
rlm
:
Realm
)
{
realm
=
rlm
...
...
@@ -24,15 +25,28 @@ public class Views {
try
setCurrentLanguage
(
context
?
.
settings
.
get
(
"user/language"
)
??
"English"
)
// Subscribe to changes in CVUStoredDefinition
#warning("Add a setting to control this (turn on and off)")
cancellable
=
context
?
.
cache
.
subscribe
(
query
:
"CVUStoredDefinition"
)
.
sink
{
items
in
// CVUStoredDefinition AND domain='user'
self
.
reloadViews
(
items
)
settingWatcher
=
context
?
.
settings
.
subscribe
(
"device/debug/autoReloadCVU"
,
type
:
Bool
.
self
)
.
sink
{
if
let
value
=
$0
as?
Bool
{
if
value
&&
self
.
CVUWatcher
==
nil
{
self
.
listenForChanges
()
}
else
if
!
value
,
let
c
=
self
.
CVUWatcher
{
c
.
cancel
()
self
.
CVUWatcher
=
nil
}
}
}
// Done
try
callback
()
}
public
func
listenForChanges
()
{
// Subscribe to changes in CVUStoredDefinition
CVUWatcher
=
context
?
.
cache
.
subscribe
(
query
:
"CVUStoredDefinition"
)
.
sink
{
items
in
// CVUStoredDefinition AND domain='user'
self
.
reloadViews
(
items
)
}
}
// TODO: refactor when implementing settings UI call this when changing the language
public
func
setCurrentLanguage
(
_
language
:
String
)
throws
{
...
...
This diff is collapsed.
Click to expand it.
memri/gui/SettingsPane.swift
+
4
-
15
View file @
d624dc04
...
...
@@ -40,20 +40,6 @@ struct SettingsPane: View {
var
body
:
some
View
{
NavigationView
{
Form
{
// Section(header: Text("General")) {
// DatePicker(selection: getBinding("/user/formatting/date"), in: ...Date(), displayedComponents: .date) {
// Text("Date Format")
// }
//
// Picker(selection: $citySelected, label: Text("Choose a city:")) {
// ForEach(0 ..< Self.cities.count) {
// Text(Self.cities[$0])
// }
// }
// if addOwnCity {
// TextField("Enter your own city" ,text: $ownCity)
// }
// }
NavigationLink
(
destination
:
Form
{
Section
(
header
:
Text
(
"Pod Connection"
),
...
...
@@ -126,8 +112,11 @@ struct SettingsPane: View {
header
:
Text
(
"Debug"
)
)
{
Toggle
(
isOn
:
getBinding
(
"/device/debug/autoShowErrorConsole"
))
{
Text
(
"Automatically pop up the debug console"
)
Text
(
"Automatically pop up the debug console
on errors
"
)
}
Toggle
(
isOn
:
getBinding
(
"/device/debug/autoReloadCVU"
))
{
Text
(
"Automatically reload CVU when it changes"
)
}
}
})
{
Text
(
"Debug"
)
...
...
This diff is collapsed.
Click to expand it.
memri/model/Cache.swift
+
11
-
1
View file @
d624dc04
...
...
@@ -560,7 +560,17 @@ public class Cache {
let
excluded
=
[
"uid"
,
"dateCreated"
,
"dateAccessed"
,
"dateModified"
]
for
prop
in
properties
{
if
!
excluded
.
contains
(
prop
.
name
),
values
[
prop
.
name
]
!=
nil
{
fromCache
[
prop
.
name
]
=
values
[
prop
.
name
]
as
Any
?
if
prop
.
type
==
.
date
{
if
let
date
=
values
[
prop
.
name
]
as?
Int
{
fromCache
[
prop
.
name
]
=
Date
(
timeIntervalSince1970
:
Double
(
date
/
1000
))
}
else
{
throw
"Invalid date received for
\(
prop
.
name
)
got
\(
String
(
describing
:
values
[
prop
.
name
]
??
""
)
)
"
}
}
else
{
fromCache
[
prop
.
name
]
=
values
[
prop
.
name
]
as
Any
?
}
}
}
fromCache
[
"dateModified"
]
=
Date
()
...
...
This diff is collapsed.
Click to expand it.
memri/model/CachePubSub.swift
+
1
-
1
View file @
d624dc04
...
...
@@ -226,7 +226,7 @@ struct QueryPublisher: Publisher {
}
func
receive
<
S
>
(
subscriber
:
S
)
where
S
:
Subscriber
,
S
.
Failure
==
QueryPublisher
.
Failure
,
S
.
Input
==
[
Item
]
{
S
.
Failure
==
QueryPublisher
.
Failure
,
S
.
Input
==
QueryPublisher
.
Output
{
// TODO
let
subscription
=
QuerySubscription
(
...
...
This diff is collapsed.
Click to expand it.
memri/model/Settings.swift
+
40
-
3
View file @
d624dc04
...
...
@@ -6,6 +6,7 @@
import
Foundation
import
RealmSwift
import
Combine
/// This class stores the settings used in the memri app. Settings may include things like how to format dates, whether to show certain
/// buttons by default, etc.
...
...
@@ -14,6 +15,9 @@ public class Settings {
let
realm
:
Realm
/// Default settings
var
settings
:
Results
<
Setting
>
private
var
listeners
=
[
String
:
[
UUID
]]()
private
var
callbacks
=
[
UUID
:
(
Any
?)
->
Void
]()
/// Init settings with the relam database
/// - Parameter rlm: realm database object
...
...
@@ -64,7 +68,8 @@ public class Settings {
}
private
func
getSearchPaths
(
_
path
:
String
)
throws
->
[
String
]
{
let
splits
=
path
.
split
(
separator
:
"/"
)
let
p
=
path
.
first
==
"/"
?
String
(
path
.
suffix
(
path
.
count
-
1
))
:
path
let
splits
=
p
.
split
(
separator
:
"/"
)
let
type
=
splits
.
first
let
query
=
splits
.
dropFirst
()
.
joined
(
separator
:
"/"
)
...
...
@@ -88,6 +93,7 @@ public class Settings {
throw
"Missing scope 'user' or 'device' as the start of the path"
}
try
setSetting
(
searchPaths
[
0
],
value
as?
AnyCodable
??
AnyCodable
(
value
))
fire
(
searchPaths
[
0
],
(
value
as?
AnyCodable
)?
.
value
??
value
)
}
catch
{
debugHistory
.
error
(
"
\(
error
)
"
)
print
(
error
)
...
...
@@ -97,7 +103,7 @@ public class Settings {
/// get setting for given path
/// - Parameter path: path for the setting
/// - Returns: setting value
public
func
getSetting
<
T
:
Decodable
>
(
_
path
:
String
)
throws
->
T
?
{
public
func
getSetting
<
T
:
Decodable
>
(
_
path
:
String
,
type
:
T
.
Type
=
T
.
self
)
throws
->
T
?
{
let
item
=
settings
.
first
(
where
:
{
$0
.
key
==
path
})
if
let
item
=
item
,
let
json
=
item
.
json
{
...
...
@@ -136,7 +142,38 @@ public class Settings {
}
}
}
private
func
fire
(
_
path
:
String
,
_
value
:
Any
?)
{
if
let
list
=
self
.
listeners
[
path
]
{
for
id
in
list
{
if
let
f
=
self
.
callbacks
[
id
]
{
f
(
value
)
}
}
}
}
func
addListener
<
T
:
Decodable
>
(
_
path
:
String
,
_
id
:
UUID
,
type
:
T
.
Type
=
T
.
self
,
_
f
:
@escaping
(
Any
?)
->
Void
)
throws
{
guard
let
normalizedPath
=
try
getSearchPaths
(
path
)
.
first
else
{
throw
"Invalid path"
}
if
self
.
listeners
[
normalizedPath
]
==
nil
{
self
.
listeners
[
normalizedPath
]
=
[]
}
if
!
(
self
.
listeners
[
normalizedPath
]?
.
contains
(
id
)
??
false
)
{
self
.
listeners
[
normalizedPath
]?
.
append
(
id
)
self
.
callbacks
[
id
]
=
f
if
let
value
=
get
(
path
,
type
:
T
.
self
)
{
fire
(
normalizedPath
,
value
)
}
}
}
func
removeListener
(
_
path
:
String
,
_
id
:
UUID
)
{
self
.
listeners
[
path
]?
.
removeAll
(
where
:
{
$0
==
id
})
self
.
callbacks
.
removeValue
(
forKey
:
id
)
}
/// Get *global* setting value for given path
/// - Parameter path: global setting path
/// - Returns: setting value
...
...
This diff is collapsed.
Click to expand it.
memri/model/SettingsPubSub.swift
0 → 100644
+
77
-
0
View file @
d624dc04
//
// SettingsPubSub.swift
//
// Copyright © 2020 memri. All rights reserved.
//
import
Combine
import
Foundation
import
RealmSwift
final
class
SettingSubscription
<
SubscriberType
:
Subscriber
,
T
:
Decodable
>
:
Subscription
where
SubscriberType
.
Input
==
Any
?
{
private
var
id
=
UUID
()
private
var
subscriber
:
SubscriberType
?
private
let
path
:
String
private
let
settings
:
Settings
init
(
settings
:
Settings
,
subscriber
:
SubscriberType
,
path
:
String
,
type
:
T
.
Type
)
{
self
.
subscriber
=
subscriber
self
.
path
=
path
self
.
settings
=
settings
do
{
try
self
.
settings
.
addListener
(
path
,
id
,
type
:
type
)
{
value
in
_
=
subscriber
.
receive
(
value
)
}
}
catch
let
error
{
debugHistory
.
warn
(
"Unable to set listener for setting:
\(
path
)
:
\(
error
)
"
)
}
}
func
request
(
_
demand
:
Subscribers
.
Demand
)
{
// We do nothing here as we only want to send events when they occur.
// See, for more info: https://developer.apple.com/documentation/combine/subscribers/demand
}
func
cancel
()
{
self
.
settings
.
removeListener
(
path
,
id
)
subscriber
=
nil
}
}
struct
SettingPublisher
<
T
:
Decodable
>
:
Publisher
{
typealias
Output
=
Any
?
typealias
Failure
=
Never
let
path
:
String
let
settings
:
Settings
let
type
:
T
.
Type
init
(
settings
:
Settings
,
path
:
String
,
type
:
T
.
Type
)
{
self
.
path
=
path
self
.
settings
=
settings
self
.
type
=
type
}
func
receive
<
S
>
(
subscriber
:
S
)
where
S
:
Subscriber
,
S
.
Failure
==
SettingPublisher
.
Failure
,
S
.
Input
==
SettingPublisher
.
Output
{
// TODO
let
subscription
=
SettingSubscription
(
settings
:
self
.
settings
,
subscriber
:
subscriber
,
path
:
path
,
type
:
type
)
subscriber
.
receive
(
subscription
:
subscription
)
}
}
extension
Settings
{
func
subscribe
<
T
>
(
_
path
:
String
,
type
:
T
.
Type
=
T
.
self
)
->
SettingPublisher
<
T
>
{
return
SettingPublisher
(
settings
:
self
,
path
:
path
,
type
:
T
.
self
)
}
}
This diff is collapsed.
Click to expand it.
memri/model/Sync.swift
+
1
-
1
View file @
d624dc04
...
...
@@ -160,7 +160,7 @@ class Sync {
// We no longer need to process this log item
realmWriteIfAvailable
(
self
.
realm
)
{
self
.
realm
.
delete
(
audititem
)
audititem
.
setSyncStateActionNeeded
(
""
)
}
}
}
else
{
...
...
This diff is collapsed.
Click to expand it.
memri/model/defaults/default_database.json
+
1
-
0
View file @
d624dc04
...
...
@@ -7,6 +7,7 @@
{
"_type"
:
"Setting"
,
"key"
:
"defaults/pod/username"
,
"value"
:
""
},
{
"_type"
:
"Setting"
,
"key"
:
"defaults/pod/password"
,
"value"
:
""
},
{
"_type"
:
"Setting"
,
"key"
:
"defaults/debug/autoShowErrorConsole"
,
"value"
:
false
},
{
"_type"
:
"Setting"
,
"key"
:
"defaults/debug/autoReloadCVU"
,
"value"
:
true
},
{
"_type"
:
"NavigationItem"
,
"type"
:
"heading"
,
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Snippets