motion-prime 0.6.0 → 0.7.0
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 +4 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +6 -1
- data/ROADMAP.md +7 -6
- data/bin/prime +31 -16
- data/doc/code/models.rb +5 -1
- data/doc/code/tables.rb +54 -0
- data/doc/docs/getting_started.html +7 -0
- data/doc/docs/index.html +205 -0
- data/doc/docs/models.html +13 -0
- data/doc/docs/screens.html +7 -0
- data/doc/docs/sections.html +7 -0
- data/doc/docs/tables.html +128 -0
- data/files/Gemfile +3 -3
- data/lib/motion-prime.rb +2 -0
- data/motion-prime.gemspec +3 -2
- data/motion-prime/api_client.rb +35 -36
- data/motion-prime/config/base.rb +0 -2
- data/motion-prime/core_ext/kernel.rb +2 -1
- data/motion-prime/elements/base_element.rb +7 -2
- data/motion-prime/elements/spinner.rb +7 -0
- data/motion-prime/elements/table_view.rb +7 -0
- data/motion-prime/helpers/has_search_bar.rb +11 -5
- data/motion-prime/models/_finder_mixin.rb +5 -12
- data/motion-prime/models/_nano_bag_mixin.rb +1 -1
- data/motion-prime/models/_sync_mixin.rb +52 -37
- data/motion-prime/screens/_base_mixin.rb +4 -0
- data/motion-prime/screens/_navigation_mixin.rb +3 -3
- data/motion-prime/screens/screen.rb +1 -1
- data/motion-prime/sections/base_section.rb +12 -12
- data/motion-prime/sections/form/base_field_section.rb +1 -1
- data/motion-prime/sections/form/date_field_section.rb +5 -0
- data/motion-prime/sections/form/password_field_section.rb +1 -1
- data/motion-prime/sections/form/string_field_section.rb +1 -1
- data/motion-prime/sections/form/text_field_section.rb +1 -1
- data/motion-prime/sections/table.rb +7 -0
- data/motion-prime/sections/table/table_delegate.rb +14 -4
- data/motion-prime/support/mp_spinner.rb +16 -0
- data/motion-prime/support/mp_table_view.rb +6 -0
- data/motion-prime/support/tab_bar_controller.rb +3 -3
- data/motion-prime/support/temp_fixes.rb +6 -0
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/layout.rb +2 -1
- data/motion-prime/views/view_builder.rb +1 -1
- metadata +24 -2
data/doc/docs/screens.html
CHANGED
data/doc/docs/sections.html
CHANGED
@@ -0,0 +1,128 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<title>tables.rb</title>
|
6
|
+
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
7
|
+
<link rel="stylesheet" media="all" href="public/stylesheets/normalize.css" />
|
8
|
+
<link rel="stylesheet" media="all" href="docco.css" />
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<div class="container">
|
12
|
+
<div class="page">
|
13
|
+
|
14
|
+
<div class="header">
|
15
|
+
|
16
|
+
<h1>tables.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>
|
37
|
+
|
38
|
+
|
39
|
+
<li>
|
40
|
+
<a class="source" href="screens.html">
|
41
|
+
screens.rb
|
42
|
+
</a>
|
43
|
+
</li>
|
44
|
+
|
45
|
+
|
46
|
+
<li>
|
47
|
+
<a class="source" href="sections.html">
|
48
|
+
sections.rb
|
49
|
+
</a>
|
50
|
+
</li>
|
51
|
+
|
52
|
+
|
53
|
+
<li>
|
54
|
+
<a class="source" href="tables.html">
|
55
|
+
tables.rb
|
56
|
+
</a>
|
57
|
+
</li>
|
58
|
+
|
59
|
+
</ol>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
</div>
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
<p><strong> What is a TableSection? </strong></p>
|
67
|
+
<p>"TableSection" is a "Section" which have some sugar to work with UITableViews.</p>
|
68
|
+
<p><strong> Create a Cell Section. </strong></p>
|
69
|
+
<p>Inherit it from <code>Prime::Section</code>. </p>
|
70
|
+
<p>Each element inside this section will be part of one cell.</p>
|
71
|
+
|
72
|
+
|
73
|
+
<div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooCellSection</span> <span class="inheritance">< <span class="parent">Prime::Section</span></span></span>
|
74
|
+
element <span class="symbol">:title</span>, <span class="symbol">text:</span> proc { model[<span class="symbol">:title</span>] }
|
75
|
+
<span class="keyword">end</span></pre></div>
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
<p><strong> Create a Table Section. </strong></p>
|
80
|
+
<p>Just inherit it from <code>Prime::TableSection</code>. </p>
|
81
|
+
<p>The key method which should be created is <code>table_data</code>. It should return array of any sections.</p>
|
82
|
+
|
83
|
+
|
84
|
+
<div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooTableSection</span> <span class="inheritance">< <span class="parent">Prime::TableSection</span></span></span>
|
85
|
+
<span class="function"><span class="keyword">def</span> <span class="title">table_data</span></span>
|
86
|
+
my_foo_items.map <span class="keyword">do</span> |fruit_name|
|
87
|
+
model = {<span class="symbol">title:</span> fruit_name}
|
88
|
+
<span class="constant">FooCellSection</span>.new(<span class="symbol">model:</span> model)
|
89
|
+
<span class="keyword">end</span>
|
90
|
+
<span class="keyword">end</span>
|
91
|
+
|
92
|
+
<span class="function"><span class="keyword">def</span> <span class="title">my_foo_items</span></span>
|
93
|
+
<span class="string">%w[Orange Apricot Banana]</span>
|
94
|
+
<span class="keyword">end</span>
|
95
|
+
<span class="keyword">end</span></pre></div>
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
<p><strong> Render table to a Screen. </strong></p>
|
100
|
+
|
101
|
+
|
102
|
+
<div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">FooScreen</span> <span class="inheritance">< <span class="parent">Prime::Screen</span></span></span>
|
103
|
+
<span class="function"><span class="keyword">def</span> <span class="title">render</span></span>
|
104
|
+
<span class="variable">@main_section</span> = <span class="constant">FooTableSection</span>.new(<span class="symbol">screen:</span> <span class="keyword">self</span>)
|
105
|
+
<span class="variable">@main_section</span>.render
|
106
|
+
<span class="keyword">end</span>
|
107
|
+
<span class="keyword">end</span></pre></div>
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
<p><strong> Style it. </strong></p>
|
112
|
+
<p>Of course, don't forget to add styles for table cells.</p>
|
113
|
+
|
114
|
+
|
115
|
+
<div class='highlight'><pre><span class="constant">Prime::Styles</span>.define <span class="symbol">:foo_cell</span> <span class="keyword">do</span>
|
116
|
+
style <span class="symbol">:title</span>,
|
117
|
+
<span class="symbol">left:</span> <span class="number">20</span>,
|
118
|
+
<span class="symbol">top:</span> <span class="number">5</span>,
|
119
|
+
<span class="symbol">width:</span> <span class="number">200</span>,
|
120
|
+
<span class="symbol">height:</span> <span class="number">20</span>
|
121
|
+
<span class="keyword">end</span></pre></div>
|
122
|
+
|
123
|
+
|
124
|
+
<div class="fleur">h</div>
|
125
|
+
</div>
|
126
|
+
</div>
|
127
|
+
</body>
|
128
|
+
</html>
|
data/files/Gemfile
CHANGED
@@ -5,10 +5,10 @@ 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.
|
8
|
+
gem 'motion-prime', '0.7.0'
|
9
9
|
|
10
10
|
# add reside menu for sidebar support
|
11
|
-
gem 'prime_reside_menu', '~> 0.1.
|
11
|
+
gem 'prime_reside_menu', '~> 0.1.4'
|
12
12
|
|
13
13
|
# or add sliding menu for sidebar support
|
14
|
-
# gem 'prime_sliding_menu', '~> 0.1.
|
14
|
+
# gem 'prime_sliding_menu', '~> 0.1.3'
|
data/lib/motion-prime.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'motion-require'
|
2
2
|
require 'motion-support'
|
3
|
+
require 'motion-support/core_ext/hash'
|
3
4
|
require 'sugarcube-common'
|
4
5
|
require 'bubble-wrap'
|
5
6
|
require 'bubble-wrap/reactor'
|
6
7
|
require 'rm-digest'
|
8
|
+
require 'afmotion'
|
7
9
|
require File.expand_path('../../motion-prime/env.rb', __FILE__)
|
8
10
|
require File.expand_path('../../motion-prime/prime.rb', __FILE__)
|
9
11
|
|
data/motion-prime.gemspec
CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_dependency "motion-support"
|
27
27
|
spec.add_dependency 'bubble-wrap'
|
28
28
|
spec.add_dependency 'sugarcube'
|
29
|
-
spec.add_dependency
|
30
|
-
spec.add_dependency
|
29
|
+
spec.add_dependency 'afmotion', '~> 2.0.0'
|
30
|
+
spec.add_dependency "methadone"
|
31
|
+
spec.add_dependency "rm-digest"
|
31
32
|
end
|
data/motion-prime/api_client.rb
CHANGED
@@ -3,27 +3,23 @@ class ApiClient
|
|
3
3
|
|
4
4
|
def initialize(options = {})
|
5
5
|
self.access_token = options[:access_token]
|
6
|
+
AFMotion::Client.build_shared(config.base) do
|
7
|
+
header "Accept", "application/json"
|
8
|
+
response_serializer AFJSONResponseSerializer.serializerWithReadingOptions(NSJSONReadingMutableContainers)
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
12
|
def request_params(data)
|
9
|
-
|
10
|
-
|
11
|
-
params = {
|
12
|
-
payload: data,
|
13
|
-
no_redirect: !config.allow_redirect,
|
14
|
-
format: config.request_format
|
15
|
-
}
|
16
|
-
if files.present?
|
17
|
-
params.merge!(files: files)
|
18
|
-
end
|
13
|
+
params = data.clone
|
14
|
+
|
19
15
|
if config.http_auth?
|
20
16
|
params.merge!(credentials: config.http_auth.to_hash)
|
21
17
|
end
|
22
18
|
if config.sign_request?
|
23
19
|
signature = RmDigest::MD5.hexdigest(
|
24
|
-
config.signature_secret +
|
20
|
+
config.signature_secret + params.keys.map(&:to_s).sort.join
|
25
21
|
)
|
26
|
-
params
|
22
|
+
params.merge!(sign: signature)
|
27
23
|
end
|
28
24
|
params
|
29
25
|
end
|
@@ -37,24 +33,15 @@ class ApiClient
|
|
37
33
|
client_secret: config.client_secret
|
38
34
|
}
|
39
35
|
use_callback = block_given?
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
parse_json(body)
|
44
|
-
else
|
45
|
-
false
|
46
|
-
end
|
36
|
+
AFMotion::Client.shared.post(config.auth_path, request_params(data)) do |response|
|
37
|
+
auth_data = response.object
|
38
|
+
|
47
39
|
self.access_token = auth_data[:access_token] if auth_data
|
48
|
-
block.call(auth_data, response.
|
40
|
+
block.call(auth_data, response.operation.response.statusCode) if use_callback
|
49
41
|
end
|
50
42
|
true
|
51
43
|
end
|
52
44
|
|
53
|
-
def api_url(path)
|
54
|
-
return path if path =~ /^http(s)?:\/\//
|
55
|
-
"#{config.base}#{config.api_namespace}#{path}"
|
56
|
-
end
|
57
|
-
|
58
45
|
def page_url(path)
|
59
46
|
"#{config.base}#{path}"
|
60
47
|
end
|
@@ -67,13 +54,22 @@ class ApiClient
|
|
67
54
|
|
68
55
|
def request(method, path, params = {}, options = {}, &block)
|
69
56
|
params.merge!(access_token: access_token)
|
57
|
+
data = request_params(params)
|
58
|
+
files = data.delete(:_files)
|
70
59
|
use_callback = block_given?
|
71
|
-
|
72
|
-
|
60
|
+
|
61
|
+
client_method = files.present? ? :"multipart_#{method}" : method
|
62
|
+
AFMotion::Client.shared.send client_method, "#{config.api_namespace}#{path}", data do |response, form_data, progress|
|
63
|
+
if form_data && files.present?
|
64
|
+
files.each do |file_data|
|
65
|
+
form_data.appendPartWithFileData(file_data[:data], name: file_data[:name], fileName:"avatar.png", mimeType: "image/jpeg")
|
66
|
+
end
|
67
|
+
elsif progress
|
68
|
+
# handle progress
|
69
|
+
elsif !response.success? && options[:allow_queue] && config.allow_queue?
|
73
70
|
add_to_queue(method: method, path: path, params: params)
|
74
71
|
else
|
75
|
-
|
76
|
-
block.call(json, response.status_code) if use_callback
|
72
|
+
block.call(prepared_object(response.object), response.operation.response.statusCode) if use_callback
|
77
73
|
process_queue
|
78
74
|
end
|
79
75
|
end
|
@@ -117,14 +113,17 @@ class ApiClient
|
|
117
113
|
MotionPrime::Config.api_client
|
118
114
|
end
|
119
115
|
|
120
|
-
def parse_json(text)
|
121
|
-
Prime::JSON.parse(text)
|
122
|
-
rescue
|
123
|
-
NSLog("Can't parse json: #{text}")
|
124
|
-
false
|
125
|
-
end
|
126
|
-
|
127
116
|
def user_defaults
|
128
117
|
@user_defaults ||= NSUserDefaults.standardUserDefaults
|
129
118
|
end
|
119
|
+
|
120
|
+
def prepared_object(object)
|
121
|
+
if object.is_a?(Hash)
|
122
|
+
object.with_indifferent_access
|
123
|
+
elsif object.is_a?(Array)
|
124
|
+
object.map(&:with_indifferent_access)
|
125
|
+
else
|
126
|
+
object
|
127
|
+
end
|
128
|
+
end
|
130
129
|
end
|
data/motion-prime/config/base.rb
CHANGED
@@ -18,8 +18,6 @@ MotionPrime::Config.configure do |config|
|
|
18
18
|
api.sign_request = false
|
19
19
|
api.auth_path = '/oauth/token'
|
20
20
|
api.api_namespace = '/api'
|
21
|
-
api.request_format = :form_data
|
22
|
-
api.allow_redirect = false
|
23
21
|
api.allow_queue = false
|
24
22
|
end
|
25
23
|
config.prime.cell_section.mixins = [Prime::CellSectionMixin]
|
@@ -17,8 +17,9 @@ class Kernel
|
|
17
17
|
|
18
18
|
def clear_instance_variables(options = {})
|
19
19
|
ivars = self.instance_variables
|
20
|
+
excluded_ivars = Array.wrap(options[:except]).map(&:to_s)
|
20
21
|
clear_block = proc { |ivar|
|
21
|
-
next if
|
22
|
+
next if excluded_ivars.include?(ivar[1..-1])
|
22
23
|
self.instance_variable_set(ivar, nil)
|
23
24
|
}.weak!
|
24
25
|
ivars.each(&clear_block)
|
@@ -29,7 +29,7 @@ module MotionPrime
|
|
29
29
|
end
|
30
30
|
|
31
31
|
# def dealloc
|
32
|
-
# pp '
|
32
|
+
# pp 'Deallocating elemenet', self.name, self.to_s, view_class#, view.try(:to_s)
|
33
33
|
# super
|
34
34
|
# end
|
35
35
|
|
@@ -45,10 +45,15 @@ module MotionPrime
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def render!(&block)
|
48
|
-
screen.add_view class_factory(view_class), computed_options do |view|
|
48
|
+
view = screen.add_view class_factory(view_class), computed_options do |view|
|
49
49
|
@view = view
|
50
50
|
block.try(:call, view, self)
|
51
51
|
end
|
52
|
+
|
53
|
+
if computed_options.has_key?(:delegate) && computed_options[:delegate].respond_to?(:delegated_by)
|
54
|
+
computed_options[:delegate].delegated_by(view)
|
55
|
+
end
|
56
|
+
view
|
52
57
|
end
|
53
58
|
|
54
59
|
# Lazy-computing options
|
@@ -4,21 +4,27 @@ module MotionPrime
|
|
4
4
|
def add_search_bar(options = {}, &block)
|
5
5
|
target = options.delete(:target)
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
@_search_bar = create_search_bar(options)
|
8
|
+
@_search_bar.setDelegate self
|
9
9
|
|
10
10
|
if target
|
11
|
-
target.addSubview
|
11
|
+
target.addSubview @_search_bar
|
12
12
|
elsif is_a?(TableSection)
|
13
|
-
self.table_view.tableHeaderView =
|
13
|
+
self.table_view.tableHeaderView = @_search_bar
|
14
14
|
end
|
15
15
|
|
16
16
|
@search_callback = block
|
17
|
-
|
17
|
+
@_search_bar
|
18
18
|
rescue
|
19
19
|
NSLog("can't add search bar to #{self.class_name_without_kvo}")
|
20
20
|
end
|
21
21
|
|
22
|
+
def dealloc
|
23
|
+
@_search_bar.try(:setDelegate, nil)
|
24
|
+
@_search_bar = nil
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
22
28
|
def create_search_bar(options = {})
|
23
29
|
name = is_a?(TableSection) ? name : self.class_name_without_kvo.underscore
|
24
30
|
screen = is_a?(TableSection) ? self.screen : self
|
@@ -42,7 +42,7 @@ module MotionPrime
|
|
42
42
|
# Find model by criteria
|
43
43
|
#
|
44
44
|
# @example:
|
45
|
-
# User.find(
|
45
|
+
# User.find(1) # => [<User#1>]
|
46
46
|
# User.find(:name => "Bob") # => [<User#1>]
|
47
47
|
# User.find(:name => {NSFEqualTo => "Bob"}) # => [<User#1>]
|
48
48
|
#
|
@@ -56,19 +56,12 @@ module MotionPrime
|
|
56
56
|
else
|
57
57
|
sort_options = {}
|
58
58
|
end
|
59
|
-
elsif arg[0] && arg[
|
60
|
-
|
61
|
-
options = {arg[0] => {arg[1] => arg[2]}}
|
62
|
-
if arg[4] && arg[4].is_a?(Hash)
|
63
|
-
sort_options = arg[4][:sort] || {}
|
64
|
-
else
|
65
|
-
sort_options = {}
|
66
|
-
end
|
59
|
+
elsif arg[0] && arg[0].is_a?(Integer)
|
60
|
+
return find(id: arg[0])
|
67
61
|
elsif arg.empty?
|
68
|
-
|
69
|
-
sort_options = {}
|
62
|
+
raise "Please use Model#all to find all records."
|
70
63
|
else
|
71
|
-
raise "
|
64
|
+
raise "Unexpected parameters: #{arg}."
|
72
65
|
end
|
73
66
|
search = NSFNanoSearch.searchWithStore(self.store)
|
74
67
|
|