motion-prime 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/motion-prime/app_delegate.rb +11 -8
- data/motion-prime/models/_association_mixin.rb +3 -0
- data/motion-prime/models/_base_mixin.rb +63 -16
- data/motion-prime/models/_finder_mixin.rb +10 -6
- data/motion-prime/models/_nano_bag_mixin.rb +4 -4
- data/motion-prime/models/_sync_mixin.rb +65 -12
- data/motion-prime/screens/_base_mixin.rb +5 -0
- data/motion-prime/screens/_navigation_mixin.rb +14 -12
- data/motion-prime/sections/base_section.rb +42 -0
- data/motion-prime/sections/table.rb +3 -0
- data/motion-prime/sections/table/table_delegate.rb +4 -0
- data/motion-prime/support/tab_bar_controller.rb +5 -6
- data/motion-prime/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NWRjNTUxZWEzMTQzYjA3YTQ1ZjY4YmU2ZDdlZGQ3OGY1MzQ0NzJhYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDAyNzdlMjM1N2U0Mzk2MmFhNzJmZTM1OGRhNGVmMjBjMjEzZTkwYQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MDFlYjZhYjMxOTM0NjIxMTYzZDQ3ZjA5M2ZkMTQzMTYyMmFmY2QzOWFlODU4
|
10
|
+
MTc1YTRmYjBhNjA0NDA0N2I5MjA0Y2U0ZWYxMzZmMjIyZWJkYWIzYjkxYWVj
|
11
|
+
ZmZjOTdkMGMxNTFiZWE5NGI4YTA2MDg3NjM5YTY4YmNiMTJjNzM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
N2FlNDdlYjQzZDUyZjVlZTZiNjA1MDA1ZGI4MjI5M2Q1ZjFkMzY5ZmI5OTVi
|
14
|
+
YjA3ZmU0NzNlN2E0YjI0ZTYyMjQ2NGJlOTliMDE0OTM2Mjg2NmExODljZDBk
|
15
|
+
ZmRiYTRiMGE4N2RkZTc3MmI1MjlhNGY1NjVjMDU1OTJlYWNmOWY=
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
=== 0.5.6
|
2
|
+
* sending "title" in options is not supported now. use dsl with Proc for that.
|
3
|
+
* ability to open root screen with animation.
|
4
|
+
* refactored screens navigation.
|
5
|
+
|
1
6
|
=== 0.5.5
|
2
7
|
* improve association fetch speed and login.
|
3
8
|
* "delete" method is not supported for model collection now, use delete_all.
|
data/Gemfile.lock
CHANGED
@@ -42,9 +42,9 @@ module MotionPrime
|
|
42
42
|
def open_screen(screen, options = {})
|
43
43
|
screen = prepare_screen_for_open(screen, options)
|
44
44
|
if options[:root] || !self.window
|
45
|
-
open_root_screen(screen)
|
45
|
+
open_root_screen(screen, options)
|
46
46
|
else
|
47
|
-
open_content_screen(screen)
|
47
|
+
open_content_screen(screen, options)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -62,7 +62,6 @@ module MotionPrime
|
|
62
62
|
|
63
63
|
private
|
64
64
|
def prepare_screen_for_open(screen, options = {})
|
65
|
-
screen = create_tab_bar(screen) if screen.is_a?(Array)
|
66
65
|
Screen.create_with_options(screen, true, options)
|
67
66
|
end
|
68
67
|
|
@@ -73,7 +72,15 @@ module MotionPrime
|
|
73
72
|
screen = screen.main_controller if screen.respond_to?(:main_controller)
|
74
73
|
|
75
74
|
self.window ||= UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
76
|
-
|
75
|
+
if options[:animated]
|
76
|
+
UIView.transitionWithView self.window,
|
77
|
+
duration: 0.5,
|
78
|
+
options: UIViewAnimationOptionTransitionFlipFromLeft,
|
79
|
+
animations: proc { self.window.rootViewController = screen },
|
80
|
+
completion: nil
|
81
|
+
else
|
82
|
+
self.window.rootViewController = screen
|
83
|
+
end
|
77
84
|
self.window.makeKeyAndVisible
|
78
85
|
screen
|
79
86
|
end
|
@@ -81,9 +88,5 @@ module MotionPrime
|
|
81
88
|
def open_content_screen(screen, options = {})
|
82
89
|
open_root_screen(screen)
|
83
90
|
end
|
84
|
-
|
85
|
-
def create_tab_bar(screens)
|
86
|
-
MotionPrime::TabBarController.new(screens)
|
87
|
-
end
|
88
91
|
end
|
89
92
|
end
|
@@ -6,6 +6,9 @@ module MotionPrime
|
|
6
6
|
base.class_attribute :default_sort_options
|
7
7
|
end
|
8
8
|
|
9
|
+
# Saves model to default store.
|
10
|
+
#
|
11
|
+
# @return [Prime::Model] model
|
9
12
|
def save
|
10
13
|
raise StoreError, 'No store provided' unless self.store
|
11
14
|
error_ptr = Pointer.new(:id)
|
@@ -14,6 +17,9 @@ module MotionPrime
|
|
14
17
|
self
|
15
18
|
end
|
16
19
|
|
20
|
+
# Removed model from default store.
|
21
|
+
#
|
22
|
+
# @return [Prime::Model] model
|
17
23
|
def delete
|
18
24
|
raise StoreError, 'No store provided' unless self.store
|
19
25
|
|
@@ -27,6 +33,13 @@ module MotionPrime
|
|
27
33
|
super || self.class.store
|
28
34
|
end
|
29
35
|
|
36
|
+
# Assigns attributes to model
|
37
|
+
#
|
38
|
+
# @params attributes [Hash] attributes to be assigned
|
39
|
+
# @params options [Hash] options
|
40
|
+
# @option options [Boolean] :skip_nil_values Do not assign nil values
|
41
|
+
# @option options [Boolean] :validate_attribute_presence Raise error if model do not have attribute
|
42
|
+
# @return [Hash] attributes
|
30
43
|
def assign_attributes(new_attributes, options = {})
|
31
44
|
attributes = new_attributes.symbolize_keys
|
32
45
|
attributes.each do |k, v|
|
@@ -40,30 +53,54 @@ module MotionPrime
|
|
40
53
|
end
|
41
54
|
end
|
42
55
|
|
56
|
+
# Assigns attribute to model
|
57
|
+
#
|
58
|
+
# @params name [String, Symbol] attribute name
|
59
|
+
# @params value [Object] attribute value
|
60
|
+
# @return [Object] assigned object if has been assigned
|
43
61
|
def assign_attribute(name, value)
|
44
62
|
self.send("#{name}=", value) if has_attribute?(name)
|
45
63
|
end
|
46
64
|
|
65
|
+
# Check if model has attribute
|
66
|
+
#
|
67
|
+
# @params name [String, Symbol] attribute name
|
68
|
+
# @return [Boolean] result
|
47
69
|
def has_attribute?(name)
|
48
70
|
respond_to?("#{name}=")
|
49
71
|
end
|
50
72
|
|
73
|
+
# Hash of all attributes in model
|
74
|
+
#
|
75
|
+
# @return [Hash] key-value hash
|
51
76
|
def attributes_hash
|
52
77
|
self.info.to_hash.symbolize_keys
|
53
78
|
end
|
54
79
|
|
80
|
+
# Checks if model has been saved in server (have an ID)
|
81
|
+
#
|
82
|
+
# @return [Boolean] true if model is not saved
|
55
83
|
def new_record?
|
56
84
|
id.blank?
|
57
85
|
end
|
58
86
|
|
87
|
+
# Checks if model has been saved in server (have an ID)
|
88
|
+
#
|
89
|
+
# @return [Boolean] true if model is saved
|
59
90
|
def persisted?
|
60
91
|
!new_record?
|
61
92
|
end
|
62
93
|
|
94
|
+
# Model class name
|
95
|
+
#
|
96
|
+
# @return [String] model class name
|
63
97
|
def model_name
|
64
98
|
self.class_name_without_kvo.underscore
|
65
99
|
end
|
66
100
|
|
101
|
+
# Returns json-formatted representation of model
|
102
|
+
#
|
103
|
+
# @return [String] model representation
|
67
104
|
def inspect
|
68
105
|
"#<#{self.class}:0x#{self.object_id.to_s(16)}> " + MotionPrime::JSON.generate(info)
|
69
106
|
end
|
@@ -71,9 +108,12 @@ module MotionPrime
|
|
71
108
|
module ClassMethods
|
72
109
|
# Initialize a new object
|
73
110
|
#
|
74
|
-
#
|
111
|
+
# @example:
|
75
112
|
# User.new(name: "Bob", age: 10)
|
76
113
|
#
|
114
|
+
# @params attributes [Hash] attributes beeing assigned to model
|
115
|
+
# @params options [Hash] options
|
116
|
+
# @option options [Boolean] :validate_attribute_presence Raise error if model do not have attribute
|
77
117
|
# @return MotionPrime::Model unsaved model
|
78
118
|
def new(data = {}, options = {})
|
79
119
|
data.keys.each do |key|
|
@@ -90,20 +130,22 @@ module MotionPrime
|
|
90
130
|
object
|
91
131
|
end
|
92
132
|
|
93
|
-
# Initialize a new object and save it
|
133
|
+
# Initialize a new object and save it to store
|
94
134
|
#
|
95
|
-
#
|
135
|
+
# @example:
|
96
136
|
# User.create(name: "Bob", age: 10)
|
97
137
|
#
|
98
|
-
# @
|
138
|
+
# @params attributes [Hash] attributes beeing assigned to model
|
139
|
+
# @return model [MotionPrime::Model] saved model
|
99
140
|
def create(data = {})
|
100
141
|
object = self.new(data)
|
101
142
|
object.save
|
143
|
+
object
|
102
144
|
end
|
103
145
|
|
104
146
|
# Define model attribute
|
105
147
|
#
|
106
|
-
#
|
148
|
+
# @example:
|
107
149
|
# class User < MotionPrime::Model
|
108
150
|
# attribute :name
|
109
151
|
# attribute :age
|
@@ -134,46 +176,45 @@ module MotionPrime
|
|
134
176
|
end
|
135
177
|
end
|
136
178
|
|
137
|
-
# Set or return all model attribute names
|
179
|
+
# Set and/or return all model attribute names
|
138
180
|
#
|
139
|
-
# @return Array array of attribute names
|
181
|
+
# @return array [Array<Symbol>] array of attribute names
|
140
182
|
def attributes(*attrs)
|
141
183
|
if attrs.size > 0
|
142
184
|
attrs.each{|attr| attribute attr}
|
143
|
-
else
|
144
|
-
@attributes ||= []
|
145
185
|
end
|
186
|
+
@attributes ||= []
|
146
187
|
end
|
147
188
|
|
148
189
|
# Return store associated with model class, or shared store by default
|
149
190
|
#
|
150
|
-
# @return MotionPrime::Store store
|
191
|
+
# @return store [MotionPrime::Store] store
|
151
192
|
def store
|
152
193
|
@store ||= MotionPrime::Store.shared_store
|
153
194
|
end
|
154
195
|
|
155
196
|
# Define store associated with model class
|
156
197
|
#
|
157
|
-
# @param MotionPrime::Store store
|
158
|
-
# @return MotionPrime::Store store
|
198
|
+
# @param store [MotionPrime::Store] store
|
199
|
+
# @return store [MotionPrime::Store] store
|
159
200
|
def store=(store)
|
160
201
|
@store = store
|
161
202
|
end
|
162
203
|
|
163
204
|
# Count of models
|
164
205
|
#
|
165
|
-
# @return Fixnum count
|
206
|
+
# @return count [Fixnum] count of objects with this Prime::Model
|
166
207
|
def count
|
167
208
|
self.store.count(self)
|
168
209
|
end
|
169
210
|
|
170
211
|
# Delete objects from store by given options
|
171
212
|
#
|
172
|
-
#
|
213
|
+
# @example:
|
173
214
|
# User.delete(:name => "Bob") #
|
174
215
|
#
|
175
|
-
# @param [Array, MotionPrime::Model] objects to delete
|
176
|
-
# @return [Array] removed item keys
|
216
|
+
# @param options [Hash, Array, MotionPrime::Model] objects to delete. See find_keys for list of options.
|
217
|
+
# @return keys [Array] removed item keys
|
177
218
|
def delete(*args)
|
178
219
|
if args.blank?
|
179
220
|
raise "Using delete with no args is not allowed. Please use delete_all to delete all records"
|
@@ -182,6 +223,12 @@ module MotionPrime
|
|
182
223
|
self.store.delete_keys(keys)
|
183
224
|
end
|
184
225
|
|
226
|
+
# Delete all objects with this Prime::Model
|
227
|
+
#
|
228
|
+
# @example:
|
229
|
+
# User.delete_all
|
230
|
+
#
|
231
|
+
# @return keys [Array] removed item keys
|
185
232
|
def delete_all
|
186
233
|
self.store.delete_keys(find_keys)
|
187
234
|
end
|
@@ -7,7 +7,7 @@ module MotionPrime
|
|
7
7
|
|
8
8
|
# Find all models
|
9
9
|
#
|
10
|
-
# @return [Array] array of models
|
10
|
+
# @return items [Array] array of models
|
11
11
|
def all(*args)
|
12
12
|
return [] unless self.store
|
13
13
|
|
@@ -26,23 +26,27 @@ module MotionPrime
|
|
26
26
|
end
|
27
27
|
|
28
28
|
# Find last model model by default order
|
29
|
+
#
|
30
|
+
# @return item [Prime::Model] result
|
29
31
|
def last
|
30
32
|
all.last
|
31
33
|
end
|
32
34
|
|
33
35
|
# Find first model model by default order
|
36
|
+
#
|
37
|
+
# @return item [Prime::Model] result
|
34
38
|
def first
|
35
39
|
all.first
|
36
40
|
end
|
37
41
|
|
38
42
|
# Find model by criteria
|
39
43
|
#
|
40
|
-
#
|
44
|
+
# @example:
|
41
45
|
# User.find(:name, NSFEqualTo, "Bob") # => [<User#1>]
|
42
46
|
# User.find(:name => "Bob") # => [<User#1>]
|
43
47
|
# User.find(:name => {NSFEqualTo => "Bob"}) # => [<User#1>]
|
44
48
|
#
|
45
|
-
# @return [Array] array of models
|
49
|
+
# @return items [Array] array of models
|
46
50
|
def find(*arg)
|
47
51
|
if arg[0].is_a?(Hash)
|
48
52
|
# hash style
|
@@ -88,12 +92,12 @@ module MotionPrime
|
|
88
92
|
|
89
93
|
# Find model keys by criteria
|
90
94
|
#
|
91
|
-
#
|
95
|
+
# @example:
|
92
96
|
# User.find_keys(:name, NSFEqualTo, "Bob") # => ["1"]
|
93
97
|
# User.find_keys(:name => "Bob") # => ["1"]
|
94
98
|
# User.find_keys(:name => {NSFEqualTo => "Bob"}) # => ["1"]
|
95
99
|
#
|
96
|
-
# @return [Array] array of models
|
100
|
+
# @return keys [Array] array of models
|
97
101
|
def find_keys(*arg)
|
98
102
|
if arg[0].is_a?(Hash)
|
99
103
|
# hash style
|
@@ -140,7 +144,7 @@ module MotionPrime
|
|
140
144
|
|
141
145
|
# Find a model by key
|
142
146
|
#
|
143
|
-
#
|
147
|
+
# @example:
|
144
148
|
# User.find_by_key(my_key)
|
145
149
|
#
|
146
150
|
# @return [Object, Nil] an object or nil (if not found)
|
@@ -29,7 +29,7 @@ module MotionPrime
|
|
29
29
|
|
30
30
|
# Add an object or array of objects to bag
|
31
31
|
#
|
32
|
-
# @return self
|
32
|
+
# @return self [Prime::Model]
|
33
33
|
def add(object_or_array)
|
34
34
|
error_ptr = Pointer.new(:id)
|
35
35
|
prepared = prepare_for_store(object_or_array)
|
@@ -59,8 +59,8 @@ module MotionPrime
|
|
59
59
|
|
60
60
|
# Remove object from bag with key
|
61
61
|
#
|
62
|
-
# @param [String]
|
63
|
-
# @return self
|
62
|
+
# @param key [String] a key or array of keys
|
63
|
+
# @return self [Prime::Model]
|
64
64
|
def delete_key(key)
|
65
65
|
if key.is_a?(Array)
|
66
66
|
self.removeObjectsWithKeysInArray(key)
|
@@ -72,7 +72,7 @@ module MotionPrime
|
|
72
72
|
|
73
73
|
# Remove an object or array of objects from bag
|
74
74
|
#
|
75
|
-
# @param [
|
75
|
+
# @param items [Array<Prime::Model>, Prime::Model] model or array of models to remove
|
76
76
|
# @return self
|
77
77
|
def delete(object_or_array)
|
78
78
|
error_ptr = Pointer.new(:id)
|
@@ -8,19 +8,30 @@ module MotionPrime
|
|
8
8
|
base.class_attribute :_associations
|
9
9
|
end
|
10
10
|
|
11
|
+
# Get normalized sync url of this Prime::Model
|
12
|
+
#
|
13
|
+
# @param method [Symbol] http method
|
14
|
+
# @return url [String] url to use in model sync
|
11
15
|
def sync_url(method = :get, options = {})
|
12
16
|
url = self.class.sync_url
|
13
17
|
url = url.call(method, self, options) if url.is_a?(Proc)
|
14
18
|
normalize_sync_url(url)
|
15
19
|
end
|
16
20
|
|
21
|
+
# Get normalized sync url of associated Prime::Model
|
22
|
+
#
|
23
|
+
# @param key [Symbol] association name
|
24
|
+
# @return url [String] url to use in model association sync
|
17
25
|
def association_sync_url(key, options)
|
18
26
|
url = options[:sync_url]
|
19
27
|
url = url.call(self) if url.is_a?(Proc)
|
20
28
|
normalize_sync_url(url)
|
21
29
|
end
|
22
30
|
|
23
|
-
#
|
31
|
+
# Destroy model on server and delete on local
|
32
|
+
#
|
33
|
+
# @param block [Proc] block to be executed after destroy
|
34
|
+
# @return self[Prime::Model] deleted model.
|
24
35
|
def destroy(&block)
|
25
36
|
use_callback = block_given?
|
26
37
|
api_client.delete(sync_url(:delete)) do
|
@@ -29,12 +40,19 @@ module MotionPrime
|
|
29
40
|
delete
|
30
41
|
end
|
31
42
|
|
32
|
-
#
|
43
|
+
# Fetch model from server and save on local
|
44
|
+
#
|
33
45
|
def fetch!(options = {}, &block)
|
34
46
|
fetch(options.merge(save: true), &block)
|
35
47
|
end
|
36
48
|
|
37
|
-
#
|
49
|
+
# Fetch model from server
|
50
|
+
#
|
51
|
+
# @param options [Hash] fetch options
|
52
|
+
# @option options [Symbol] :method Http method to calculate url, `:get` by default
|
53
|
+
# @option options [Boolean] :associations Also fetch associations
|
54
|
+
# @option options [Boolean] :save Save model after fetch
|
55
|
+
# @param block [Proc] block to be executed after fetch
|
38
56
|
def fetch(options = {}, &block)
|
39
57
|
use_callback = block_given?
|
40
58
|
method = options[:method] || :get
|
@@ -54,12 +72,16 @@ module MotionPrime
|
|
54
72
|
end if will_fetch_associations
|
55
73
|
end
|
56
74
|
|
57
|
-
#
|
75
|
+
# Update on server and save response on local
|
76
|
+
#
|
58
77
|
def update!(options = {}, &block)
|
59
78
|
update(options.merge(save_response: true), &block)
|
60
79
|
end
|
61
80
|
|
62
|
-
#
|
81
|
+
# Update on server
|
82
|
+
# @param options [Hash] update options
|
83
|
+
# @option options [Symbol] :method Http method to calculate url, by default `:post` for new record and `:put` for existing
|
84
|
+
# @param block [Proc] block to be executed after update
|
63
85
|
def update(options = {}, &block)
|
64
86
|
use_callback = block_given?
|
65
87
|
|
@@ -72,7 +94,10 @@ module MotionPrime
|
|
72
94
|
end if will_update_model
|
73
95
|
end
|
74
96
|
|
75
|
-
#
|
97
|
+
# Fetch model from server using url
|
98
|
+
#
|
99
|
+
# @param url [String] url to fetch
|
100
|
+
# @param block [Proc] block to be executed after fetch
|
76
101
|
def fetch_with_url(url, &block)
|
77
102
|
use_callback = block_given?
|
78
103
|
api_client.get(url) do |data, status_code|
|
@@ -81,7 +106,10 @@ module MotionPrime
|
|
81
106
|
end
|
82
107
|
end
|
83
108
|
|
84
|
-
#
|
109
|
+
# Update on server using url
|
110
|
+
#
|
111
|
+
# @param url [String] url to update
|
112
|
+
# @param block [Proc] block to be executed after update
|
85
113
|
def update_with_url(url, options = {}, &block)
|
86
114
|
use_callback = block_given?
|
87
115
|
filtered_attributes = filtered_updatable_attributes(options)
|
@@ -109,14 +137,31 @@ module MotionPrime
|
|
109
137
|
fetch_with_attributes(data)
|
110
138
|
end
|
111
139
|
|
112
|
-
#
|
113
|
-
|
140
|
+
# Assign model attributes, using fetch. Differenct between assign_attributes and fetch_with_attributes is
|
141
|
+
# ths you can create method named fetch_:attribute and it will be used to assign attribute only on fetch.
|
142
|
+
#
|
143
|
+
# @example
|
144
|
+
# class User < Prime::Model
|
145
|
+
# attribute :created_at
|
146
|
+
# def fetch_created_at(value)
|
147
|
+
# self.created_at = Date.parse(value)
|
148
|
+
# end
|
149
|
+
# end
|
150
|
+
# user = User.new
|
151
|
+
# user.fetch_with_attributes(created_at: '2007-03-01T13:00:00Z')
|
152
|
+
# user.created_at # => 2007-03-01 13:00:00 UTC
|
153
|
+
#
|
154
|
+
# @params attributes [Hash] attributes to be assigned
|
155
|
+
# @params options [Hash] options
|
156
|
+
# @option options [Boolean] :save_associations Save included to hash associations
|
157
|
+
# @return model [Prime::Model] the model
|
158
|
+
def fetch_with_attributes(attrs, options = {})
|
114
159
|
track_changed_attributes do
|
115
160
|
attrs.each do |key, value|
|
116
161
|
if respond_to?(:"fetch_#{key}")
|
117
162
|
self.send(:"fetch_#{key}", value)
|
118
163
|
elsif has_association?(key) && (value.is_a?(Hash) || value.is_a?(Array))
|
119
|
-
should_save =
|
164
|
+
should_save = options[:save_associations]
|
120
165
|
fetch_association_with_attributes(key, value, save: should_save)
|
121
166
|
elsif respond_to?(:"#{key}=")
|
122
167
|
self.send(:"#{key}=", value)
|
@@ -189,7 +234,7 @@ module MotionPrime
|
|
189
234
|
def fetch_has_many_with_attributes(key, data, sync_options = {})
|
190
235
|
old_collection = self.send(key)
|
191
236
|
model_class = key.classify.constantize
|
192
|
-
self.
|
237
|
+
self.store.save_interval = data.count
|
193
238
|
# Update/Create existing records
|
194
239
|
data.each do |attributes|
|
195
240
|
model = old_collection.detect{ |model| model.id == attributes[:id]}
|
@@ -207,7 +252,7 @@ module MotionPrime
|
|
207
252
|
end
|
208
253
|
end
|
209
254
|
save if sync_options[:save]
|
210
|
-
self.
|
255
|
+
self.store.save_interval = 1
|
211
256
|
end
|
212
257
|
|
213
258
|
def fetch_has_one(key, options = {}, &block)
|
@@ -271,6 +316,14 @@ module MotionPrime
|
|
271
316
|
end
|
272
317
|
|
273
318
|
module ClassMethods
|
319
|
+
def fetch_all_with_attributes(data)
|
320
|
+
data.map do |attrs|
|
321
|
+
item = self.new
|
322
|
+
item.fetch_with_attributes(attrs)
|
323
|
+
item
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
274
327
|
def new(data = {}, options = {})
|
275
328
|
model = super
|
276
329
|
if fetch_attributes = options[:fetch_attributes]
|
@@ -71,12 +71,17 @@ module MotionPrime
|
|
71
71
|
set_callback :render, :after, method_name
|
72
72
|
end
|
73
73
|
def create_with_options(screen, navigation = true, options = {})
|
74
|
+
screen = create_tab_bar(screen, options) if screen.is_a?(Array)
|
74
75
|
if screen.is_a?(Symbol)
|
75
76
|
options[:navigation] = navigation unless options.has_key?(:navigation)
|
76
77
|
screen = class_factory("#{screen}_screen").new(options)
|
77
78
|
end
|
78
79
|
screen
|
79
80
|
end
|
81
|
+
|
82
|
+
def create_tab_bar(screens, options = {})
|
83
|
+
MotionPrime::TabBarController.new(screens, options)
|
84
|
+
end
|
80
85
|
end
|
81
86
|
end
|
82
87
|
end
|
@@ -14,7 +14,7 @@ module MotionPrime
|
|
14
14
|
screen.send(:on_screen_load) if screen.respond_to?(:on_screen_load)
|
15
15
|
args[:animated] = args.has_key?(:animated) ? args[:animated] : true
|
16
16
|
if args[:modal] || !has_navigation?
|
17
|
-
open_screen_modal(screen, args)
|
17
|
+
open_screen_modal(screen, args.merge(modal: true))
|
18
18
|
else
|
19
19
|
open_screen_navigational(screen, args)
|
20
20
|
end
|
@@ -36,12 +36,18 @@ module MotionPrime
|
|
36
36
|
close_screen
|
37
37
|
end
|
38
38
|
|
39
|
-
def send_on_return
|
39
|
+
def send_on_return
|
40
40
|
if parent_screen && parent_screen.respond_to?(:on_return)
|
41
41
|
parent_screen.send(:on_return)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
def send_on_leave
|
46
|
+
if respond_to?(:on_leave)
|
47
|
+
on_leave
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
45
51
|
def wrap_in_navigation?
|
46
52
|
options[:navigation] || options[:navigation].nil?
|
47
53
|
end
|
@@ -66,30 +72,26 @@ module MotionPrime
|
|
66
72
|
|
67
73
|
private
|
68
74
|
def setup_screen_for_open(screen, args = {})
|
69
|
-
|
70
|
-
screen = Screen.create_with_options(screen, true, args)
|
71
|
-
|
72
|
-
# Set parent, title & modal properties
|
75
|
+
screen = self.class.create_with_options(screen, true, args)
|
73
76
|
screen.parent_screen = self if screen.respond_to?("parent_screen=")
|
74
|
-
screen.title = args[:title] if args[:title] && screen.respond_to?("title=")
|
75
|
-
screen.modal = args[:modal] if args[:modal] && screen.respond_to?("modal=")
|
76
|
-
|
77
|
-
# Return modified screen instance
|
78
77
|
screen
|
79
78
|
end
|
80
79
|
|
81
80
|
def open_screen_modal(screen, args)
|
81
|
+
screen.modal = true if screen.respond_to?("modal=")
|
82
82
|
self.presentModalViewController(screen.main_controller, animated: args[:animated])
|
83
|
+
send_on_leave
|
83
84
|
end
|
84
85
|
|
85
86
|
def open_screen_navigational(screen, args = {})
|
86
87
|
navigation_controller.pushViewController(screen, animated: args[:animated])
|
88
|
+
send_on_leave
|
87
89
|
end
|
88
90
|
|
89
91
|
# @return screen [Prime::Screen] screen appearing after close
|
90
92
|
def close_screen_modal(args = {})
|
91
93
|
parent_screen.dismissViewControllerAnimated(args[:animated], completion: lambda {
|
92
|
-
send_on_return
|
94
|
+
send_on_return
|
93
95
|
})
|
94
96
|
parent_screen
|
95
97
|
end
|
@@ -111,7 +113,7 @@ module MotionPrime
|
|
111
113
|
result = self.navigation_controller.childViewControllers.last
|
112
114
|
end
|
113
115
|
end
|
114
|
-
send_on_return
|
116
|
+
send_on_return
|
115
117
|
result
|
116
118
|
end
|
117
119
|
|
@@ -46,23 +46,60 @@ module MotionPrime
|
|
46
46
|
options[:container_bounds] or raise "You must pass `container bounds` option to prerender base section"
|
47
47
|
end
|
48
48
|
|
49
|
+
# Get computed container options
|
50
|
+
#
|
51
|
+
# @return options [Hash] computed options
|
49
52
|
def container_options
|
50
53
|
compute_container_options! unless @container_options
|
51
54
|
@container_options
|
52
55
|
end
|
53
56
|
|
57
|
+
# Get computed container height
|
58
|
+
#
|
59
|
+
# @example
|
60
|
+
# class MySection < Prime::Section
|
61
|
+
# container height: proc { element(:title).content_outer_height }
|
62
|
+
# element :title, text: 'Hello world'
|
63
|
+
# end
|
64
|
+
# section = MySection.new
|
65
|
+
# section.container_height # => 46
|
66
|
+
#
|
67
|
+
# @return height [Float, Integer] computed height
|
54
68
|
def container_height
|
55
69
|
container_options[:height] || DEFAULT_CONTENT_HEIGHT
|
56
70
|
end
|
57
71
|
|
72
|
+
# Get section default name, based on class name
|
73
|
+
#
|
74
|
+
# @example
|
75
|
+
# class ProfileSection < Prime::Section
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# section = ProfileSection.new
|
79
|
+
# section.default_name # => 'profile'
|
80
|
+
# section.name # => 'profile'
|
81
|
+
#
|
82
|
+
# another_section = ProfileSection.new(name: 'another')
|
83
|
+
# another_section.default_name # => 'profile'
|
84
|
+
# another_section.name # => 'another'
|
85
|
+
#
|
86
|
+
# @return name [String] section default name
|
58
87
|
def default_name
|
59
88
|
self.class_name_without_kvo.demodulize.underscore.gsub(/\_section$/, '')
|
60
89
|
end
|
61
90
|
|
91
|
+
# Get section elements options, where the key is element name.
|
92
|
+
#
|
93
|
+
# @return options [Hash] elements options
|
62
94
|
def elements_options
|
63
95
|
self.class.elements_options || {}
|
64
96
|
end
|
65
97
|
|
98
|
+
# Create elements if they are not created yet.
|
99
|
+
# This will not cause rendering elements,
|
100
|
+
# they will be rendered immediately after that or rendered async later, based on type of section.
|
101
|
+
#
|
102
|
+
# @return result [Boolean] true if has been loaded by this thread.
|
66
103
|
def load_section
|
67
104
|
return if @section_loaded
|
68
105
|
if @section_loading
|
@@ -75,11 +112,16 @@ module MotionPrime
|
|
75
112
|
return @section_loaded = true
|
76
113
|
end
|
77
114
|
|
115
|
+
# Force load section
|
116
|
+
#
|
117
|
+
# @return result [Boolean] true if has been loaded by this thread.
|
78
118
|
def load_section!
|
79
119
|
@section_loaded = false
|
80
120
|
load_section
|
81
121
|
end
|
82
122
|
|
123
|
+
# Force reload section, will also re-render elements.
|
124
|
+
# For table view cells will also reload it's table data.
|
83
125
|
def reload_section
|
84
126
|
self.elements_to_render.values.map(&:view).flatten.each do |view|
|
85
127
|
view.removeFromSuperview if view
|
@@ -243,6 +243,9 @@ module MotionPrime
|
|
243
243
|
display_pending_cells
|
244
244
|
end
|
245
245
|
|
246
|
+
def scroll_view_did_scroll(scroll)
|
247
|
+
end
|
248
|
+
|
246
249
|
def scroll_view_did_end_dragging(scroll, willDecelerate: will_decelerate)
|
247
250
|
display_pending_cells unless @decelerating = will_decelerate
|
248
251
|
end
|
@@ -55,6 +55,10 @@ module MotionPrime
|
|
55
55
|
table_section.height_for_header_in_section(table, section)
|
56
56
|
end
|
57
57
|
|
58
|
+
def scrollViewDidScroll(scroll)
|
59
|
+
table_section.scroll_view_did_scroll(scroll)
|
60
|
+
end
|
61
|
+
|
58
62
|
def scrollViewWillBeginDragging(scroll)
|
59
63
|
table_section.scroll_view_will_begin_dragging(scroll)
|
60
64
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
class TabBarController < UITabBarController
|
3
|
-
def self.new(screens)
|
3
|
+
def self.new(screens, global_options = {})
|
4
4
|
controller = alloc.init
|
5
5
|
|
6
6
|
view_controllers = []
|
7
7
|
|
8
8
|
screens.each_with_index do |options, index|
|
9
9
|
if options.is_a?(Hash)
|
10
|
-
screen = init_screen_with_options(options, tag: index)
|
10
|
+
screen = init_screen_with_options(global_options.merge(options), tag: index)
|
11
11
|
else
|
12
12
|
screen = options
|
13
13
|
screen.tabBarItem.tag = index
|
@@ -33,10 +33,9 @@ module MotionPrime
|
|
33
33
|
|
34
34
|
protected
|
35
35
|
def self.init_screen_with_options(options, tag: tag)
|
36
|
-
screen, image, title = options
|
37
|
-
screen = Screen.create_with_options(screen).try(:weak_ref)
|
36
|
+
screen, image, title = options.delete(:screen), options.delete(:title)
|
37
|
+
screen = Screen.create_with_options(screen, true, options).try(:weak_ref)
|
38
38
|
title ||= screen.title
|
39
|
-
|
40
39
|
image = extract_image_from_options(options, with_key: :image)
|
41
40
|
screen.tabBarItem = UITabBarItem.alloc.initWithTitle title, image: image, tag: tag
|
42
41
|
|
@@ -46,7 +45,7 @@ module MotionPrime
|
|
46
45
|
end
|
47
46
|
|
48
47
|
def self.extract_image_from_options(options, with_key: key)
|
49
|
-
image = options
|
48
|
+
image = options.delete(key)
|
50
49
|
return unless image
|
51
50
|
image = image.uiimage
|
52
51
|
if options[:translucent] === false
|
data/motion-prime/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motion-prime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Iskander Haziev
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-01-
|
12
|
+
date: 2014-01-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|