motion-prime 0.5.6 → 0.5.7

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.
@@ -4,56 +4,59 @@
4
4
  <head>
5
5
  <title>sections.rb</title>
6
6
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
7
- <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
7
+ <link rel="stylesheet" media="all" href="public/stylesheets/normalize.css" />
8
8
  <link rel="stylesheet" media="all" href="docco.css" />
9
9
  </head>
10
10
  <body>
11
- <div id="container">
12
- <div id="background"></div>
13
-
14
- <ul id="jump_to">
15
- <li>
16
- <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
17
- <a class="small" href="javascript:void(0);">+</a>
18
- <div id="jump_wrapper">
19
- <div id="jump_page">
20
-
11
+ <div class="container">
12
+ <div class="page">
13
+
14
+ <div class="header">
15
+
16
+ <h1>sections.rb</h1>
17
+
18
+
19
+
20
+ <div class="toc">
21
+ <h3>Table of Contents</h3>
22
+ <ol>
23
+
24
+
25
+ <li>
26
+ <a class="source" href="getting_started.html">
27
+ getting_started.rb
28
+ </a>
29
+ </li>
30
+
31
+
32
+ <li>
33
+ <a class="source" href="models.html">
34
+ models.rb
35
+ </a>
36
+ </li>
21
37
 
22
- <a class="source" href="getting_started.html">
23
- getting_started.rb
24
- </a>
25
-
38
+
39
+ <li>
40
+ <a class="source" href="screens.html">
41
+ screens.rb
42
+ </a>
43
+ </li>
26
44
 
27
- <a class="source" href="screens.html">
28
- screens.rb
29
- </a>
30
-
45
+
46
+ <li>
47
+ <a class="source" href="sections.html">
48
+ sections.rb
49
+ </a>
50
+ </li>
31
51
 
32
- <a class="source" href="sections.html">
33
- sections.rb
34
- </a>
35
-
52
+ </ol>
36
53
  </div>
37
- </li>
38
- </ul>
39
-
40
- <ul class="sections">
41
-
42
- <li id="title">
43
- <div class="annotation">
44
- <h1>sections.rb</h1>
45
- </div>
46
- </li>
47
-
48
54
 
55
+ </div>
56
+
57
+
49
58
 
50
- <li id="section-1">
51
- <div class="annotation">
52
-
53
- <div class="pilwrap ">
54
- <a class="pilcrow" href="#section-1">&#182;</a>
55
- </div>
56
- <p><strong> What is a Section? </strong></p>
59
+ <p><strong> What is a Section? </strong></p>
57
60
  <p>&quot;Section&quot; is something like &quot;partial&quot; which you may know from RubyOnRails.
58
61
  In the first look it&#39;s just a list of elements which will be added to the &quot;Screen&quot;.
59
62
  But the magic is inside.
@@ -61,74 +64,68 @@ When you add &quot;Element&quot; to a &quot;Section&quot;, e.g. image or label,
61
64
  it will try to draw it using CALayer/CGContext/etc, instead of adding new UIView.
62
65
  That way increases application speed (especially on Table elements) by 5-10 times.</p>
63
66
  <p>Let&#39;s get started.</p>
64
-
65
- </div>
66
-
67
- <div class="content"><div class='highlight'><pre>---</pre></div></div>
68
-
69
- </li>
70
-
71
-
72
- <li id="section-2">
73
- <div class="annotation">
74
-
75
- <div class="pilwrap ">
76
- <a class="pilcrow" href="#section-2">&#182;</a>
77
- </div>
78
- <p><strong> Create a section. </strong></p>
67
+ <p><strong> Create a section. </strong></p>
79
68
  <p>Just inherit it from <code>Prime::Section</code>.</p>
80
69
 
81
- </div>
82
-
83
- <div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooSection</span> <span class="inheritance">&lt; <span class="parent">Prime::Section</span></span></span>
84
- <span class="keyword">end</span></pre></div></div>
85
-
86
- </li>
87
70
 
71
+ <div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooSection</span> <span class="inheritance">&lt; <span class="parent">Prime::Section</span></span></span>
72
+ <span class="keyword">end</span></pre></div>
88
73
 
89
- <li id="section-3">
90
- <div class="annotation">
91
-
92
- <div class="pilwrap ">
93
- <a class="pilcrow" href="#section-3">&#182;</a>
94
- </div>
95
- <p><strong> Add some elements to the section. </strong></p>
96
- <p>Each element should have name and type: &quot;image&quot;, &quot;label&quot;, &quot;button&quot;, etc.
97
- When you send <code>:text</code> option, type will be &quot;label&quot; by default.
98
- When you send <code>:image</code> option, type will be &quot;image&quot; by default.</p>
74
+
75
+
76
+ <p><strong> Add some elements to the section. </strong></p>
77
+ <p>Each element should have name and type: &quot;image&quot;, &quot;label&quot;, &quot;button&quot;, etc. </p>
78
+ <p>When you send <code>:text</code> option, type will be &quot;label&quot; by default.</p>
79
+ <p>When you send <code>:image</code> option, type will be &quot;image&quot; by default.</p>
99
80
 
100
- </div>
101
-
102
- <div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooSection</span> <span class="inheritance">&lt; <span class="parent">Prime::Section</span></span></span>
81
+
82
+ <div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooSection</span> <span class="inheritance">&lt; <span class="parent">Prime::Section</span></span></span>
103
83
  element <span class="symbol">:welcome</span>, <span class="symbol">text:</span> <span class="string">'Hello World!'</span>
104
84
  element <span class="symbol">:avatar</span>, <span class="symbol">image:</span> <span class="string">'images/users/avatar.jpg'</span>
105
85
  element <span class="symbol">:cheer</span>, <span class="symbol">type:</span> <span class="symbol">:button</span>
106
- <span class="keyword">end</span></pre></div></div>
107
-
108
- </li>
86
+ <span class="keyword">end</span></pre></div>
109
87
 
88
+
110
89
 
111
- <li id="section-4">
112
- <div class="annotation">
113
-
114
- <div class="pilwrap ">
115
- <a class="pilcrow" href="#section-4">&#182;</a>
116
- </div>
117
- <p><strong> Render Section in Screen </strong></p>
118
- <p>NOTE: You must send &quot;screen&quot; option on section initialization.</p>
90
+ <p><strong> Render Section to Screen </strong></p>
91
+ <p>NOTE: it&#39;s recommended to use instance variables for sections, e.g. <code>@main_section</code> instead of <code>main_section</code>.</p>
119
92
 
120
- </div>
121
-
122
- <div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooScreen</span> <span class="inheritance">&lt; <span class="parent">Prime::Screen</span></span></span>
93
+
94
+ <div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooScreen</span> <span class="inheritance">&lt; <span class="parent">Prime::Screen</span></span></span>
123
95
  <span class="function"><span class="keyword">def</span> <span class="title">render</span></span>
124
96
  <span class="variable">@main_section</span> = <span class="constant">FooSection</span>.new(<span class="symbol">screen:</span> <span class="keyword">self</span>)
125
97
  <span class="variable">@main_section</span>.render
126
98
  <span class="keyword">end</span>
127
- <span class="keyword">end</span></pre></div></div>
128
-
129
- </li>
99
+ <span class="keyword">end</span></pre></div>
100
+
101
+
102
+
103
+ <p><strong> Add some styles for section </strong></p>
104
+ <p>Generally styles are just attributes of UIView elements.</p>
105
+ <p>Let&#39;s style the UILabel element (:welcome label element we added above.)</p>
106
+ <p>We send :foo parameter to <code>define</code>, because we have section named <code>foo</code> (FooSection)
107
+ and :welcome parameter to <code>style</code>, because the name of element is <code>welcome</code>.</p>
108
+
109
+
110
+ <div class='highlight'><pre><span class="constant">Prime::Styles</span>.define <span class="symbol">:foo</span> <span class="keyword">do</span>
111
+ style <span class="symbol">:welcome</span>,
112
+ <span class="symbol">text_color:</span> <span class="symbol">:black</span>,
113
+ <span class="symbol">top:</span> <span class="number">100</span>,
114
+ <span class="symbol">width:</span> <span class="number">320</span>,
115
+ <span class="symbol">left:</span> <span class="number">20</span>,
116
+ <span class="symbol">font:</span> proc { <span class="symbol">:system</span>.uifont(<span class="number">20</span>) },
117
+ <span class="symbol">size_to_fit:</span> <span class="keyword">true</span>,
118
+ <span class="keyword">end</span></pre></div>
119
+
120
+
121
+
122
+ <p><strong> Next </strong></p>
123
+ <p><a href="models.html">Read more about Models</a></p>
124
+
130
125
 
131
- </ul>
126
+
127
+ <div class="fleur">h</div>
128
+ </div>
132
129
  </div>
133
130
  </body>
134
131
  </html>
@@ -5,7 +5,7 @@ gem 'motion-support', '~> 0.2.4'
5
5
  gem 'sugarcube', '~> 1.3.7', require: 'sugarcube-classic'
6
6
  gem 'bubble-wrap', '~> 1.4.0'
7
7
 
8
- gem 'motion-prime', '~> 0.5.4'
8
+ gem 'motion-prime', '~> 0.5.6'
9
9
 
10
10
  # add reside menu for sidebar support
11
11
  gem 'prime_reside_menu', '~> 0.1.3'
@@ -34,7 +34,7 @@ GEM
34
34
  bundler
35
35
  motion-cocoapods (1.4.0)
36
36
  cocoapods (>= 0.26.2)
37
- motion-prime (0.5.4)
37
+ motion-prime (0.5.6)
38
38
  bubble-wrap
39
39
  cocoapods
40
40
  methadone
@@ -67,7 +67,7 @@ PLATFORMS
67
67
  DEPENDENCIES
68
68
  bubble-wrap (~> 1.4.0)
69
69
  motion-cocoapods (~> 1.4.0)
70
- motion-prime (~> 0.5.4)
70
+ motion-prime (~> 0.5.6)
71
71
  motion-support (~> 0.2.4)
72
72
  prime_reside_menu (~> 0.1.3)
73
73
  sugarcube (~> 1.3.7)
@@ -0,0 +1,10 @@
1
+ class Time
2
+ def to_short_iso8601
3
+ clone.utc.strftime("%Y%m%dT%H%M%SZ")
4
+ end
5
+
6
+ def self.short_iso8601(time)
7
+ cached_date_formatter("yyyyMMdd'T'HHmmss'Z'").
8
+ dateFromString(time.gsub(/[\:\-]*/, ''))
9
+ end
10
+ end
@@ -15,6 +15,10 @@ module MotionPrime
15
15
  bag.save
16
16
  end
17
17
  super
18
+ rescue StoreError => e
19
+ if Prime.env.development?
20
+ raise StoreError, e.description
21
+ end
18
22
  end
19
23
 
20
24
  module ClassMethods
@@ -156,14 +156,23 @@ module MotionPrime
156
156
  attributes << name
157
157
 
158
158
  define_method(name) do |*args, &block|
159
- self.info[name]
159
+ value = self.info[name]
160
+ case options[:type].to_s
161
+ when 'time'
162
+ value = Time.short_iso8601(value) if value
163
+ end
164
+ value
160
165
  end
161
166
 
162
167
  define_method((name + "=").to_sym) do |*args, &block|
163
168
  value = args[0]
164
169
  case options[:type].to_s
165
- when 'integer' then value = value.to_i
166
- when 'float' then value = value.to_f
170
+ when 'integer'
171
+ value = value.to_i
172
+ when 'float'
173
+ value = value.to_f
174
+ when 'time'
175
+ value = value.to_short_iso8601 unless value.is_a?(String)
167
176
  end unless value.nil?
168
177
 
169
178
  self.info[name] = value
@@ -11,8 +11,14 @@ module MotionPrime
11
11
  old_attrs = self.info.clone
12
12
  result = block.call
13
13
  new_attrs = self.info.clone
14
+ new_bags = self._bags.clone
14
15
  new_attrs.each do |key, value|
15
- if value != old_attrs[key] && ! @_changed_attributes.has_key?(key.to_s)
16
+ if value != old_attrs[key] && !@_changed_attributes.has_key?(key.to_s)
17
+ @_changed_attributes[key.to_s] = old_attrs[key]
18
+ end
19
+ end
20
+ new_bags.each do |key, value|
21
+ if value.key != old_attrs[key] && !@_changed_attributes.has_key?(key.to_s)
16
22
  @_changed_attributes[key.to_s] = old_attrs[key]
17
23
  end
18
24
  end
@@ -100,8 +100,15 @@ module MotionPrime
100
100
  alias_method :clear, :delete_all
101
101
 
102
102
 
103
- def store=(store)
104
- store.addObject(self, error:nil)
103
+ def store=(store, retry_count = 0)
104
+ store.addObject(self, error: nil)
105
+ rescue Exception => e
106
+ sleep(0.1)
107
+ if retry_count == 3
108
+ raise StoreError, e.description
109
+ else
110
+ send (:store=, store, retry_count + 1)
111
+ end
105
112
  end
106
113
 
107
114
  def save
@@ -236,22 +236,24 @@ module MotionPrime
236
236
  model_class = key.classify.constantize
237
237
  self.store.save_interval = data.count
238
238
  # Update/Create existing records
239
- data.each do |attributes|
240
- model = old_collection.detect{ |model| model.id == attributes[:id]}
241
- unless model
242
- model = model_class.new
243
- self.send(:"#{key}_bag") << model
239
+ track_changed_attributes do
240
+ data.each do |attributes|
241
+ model = old_collection.detect{ |model| model.id == attributes[:id]}
242
+ unless model
243
+ model = model_class.new
244
+ self.send(:"#{key}_bag") << model
245
+ end
246
+ model.fetch_with_attributes(attributes, save_associations: sync_options[:save])
247
+ model.save if sync_options[:save] && model.has_changed?
244
248
  end
245
- model.fetch_with_attributes(attributes, save_associations: sync_options[:save])
246
- model.save if sync_options[:save] && model.has_changed?
247
- end
248
- old_collection.each do |old_model|
249
- model = data.detect{ |model| model[:id] == old_model.id}
250
- unless model
251
- old_model.delete
249
+ old_collection.each do |old_model|
250
+ model = data.detect{ |model| model[:id] == old_model.id}
251
+ unless model
252
+ old_model.delete
253
+ end
252
254
  end
253
255
  end
254
- save if sync_options[:save]
256
+ save if sync_options[:save] && has_changed?
255
257
  self.store.save_interval = 1
256
258
  end
257
259
 
@@ -271,13 +273,16 @@ module MotionPrime
271
273
  end
272
274
 
273
275
  def fetch_has_one_with_attributes(key, data, sync_options = {})
274
- model = self.send(key)
275
- unless model
276
- model = key.classify.constantize.new
277
- self.send(:"#{key}_bag") << model
276
+ track_changed_attributes do
277
+ model = self.send(key)
278
+ unless model
279
+ model = key.classify.constantize.new
280
+ self.send(:"#{key}_bag") << model
281
+ end
282
+ model.fetch_with_attributes(data)
283
+ model.save if sync_options[:save]
278
284
  end
279
- model.fetch_with_attributes(data)
280
- model.save if sync_options[:save]
285
+ save if sync_options[:save] && has_changed?
281
286
  end
282
287
 
283
288
  def filtered_updatable_attributes(options = {})
@@ -158,18 +158,22 @@ module MotionPrime
158
158
  index = opts.delete(:at)
159
159
  options = build_options_for_element(opts)
160
160
  options[:name] ||= key
161
-
162
- type = options.delete(:type)
163
- element = if self.is_a?(BaseFieldSection) || self.is_a?(BaseHeaderSection) || options.delete(:as).to_s == 'view'
164
- MotionPrime::BaseElement.factory(type, options)
161
+ element = build_element(options)
162
+ if index
163
+ new_elements_array = elements.to_a.insert(index, [key, element])
164
+ self.elements = Hash[new_elements_array]
165
165
  else
166
- MotionPrime::DrawElement.factory(type, options) || MotionPrime::BaseElement.factory(type, options)
166
+ self.elements[key] = element
167
167
  end
168
+ end
168
169
 
169
- if index
170
- self.elements = Hash[self.elements.to_a.insert index, [key, element]]
170
+ def build_element(options = {})
171
+ type = options.delete(:type)
172
+ render_as = options.delete(:as).to_s
173
+ if self.is_a?(BaseFieldSection) || self.is_a?(BaseHeaderSection) || render_as == 'view'
174
+ BaseElement.factory(type, options)
171
175
  else
172
- self.elements[key] = element
176
+ DrawElement.factory(type, options) || BaseElement.factory(type, options)
173
177
  end
174
178
  end
175
179
 
@@ -282,8 +286,11 @@ module MotionPrime
282
286
 
283
287
  protected
284
288
  def bind_keyboard_close
285
- return unless self.class.keyboard_close_bindings.present?
286
- Array.wrap(self.instance_eval(&self.class.keyboard_close_bindings[:tap_on])).each do |view|
289
+ bindings = self.class.keyboard_close_bindings
290
+ return unless bindings.present?
291
+ bind_proc = bindings[:tap_on]
292
+ bind_views = instance_eval(&bind_proc)
293
+ Array.wrap(bind_views).each do |view|
287
294
  gesture_recognizer = UITapGestureRecognizer.alloc.initWithTarget(self, action: :hide_keyboard)
288
295
  view.addGestureRecognizer(gesture_recognizer)
289
296
  gesture_recognizer.cancelsTouchesInView = false