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.
Files changed (46) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +6 -1
  5. data/ROADMAP.md +7 -6
  6. data/bin/prime +31 -16
  7. data/doc/code/models.rb +5 -1
  8. data/doc/code/tables.rb +54 -0
  9. data/doc/docs/getting_started.html +7 -0
  10. data/doc/docs/index.html +205 -0
  11. data/doc/docs/models.html +13 -0
  12. data/doc/docs/screens.html +7 -0
  13. data/doc/docs/sections.html +7 -0
  14. data/doc/docs/tables.html +128 -0
  15. data/files/Gemfile +3 -3
  16. data/lib/motion-prime.rb +2 -0
  17. data/motion-prime.gemspec +3 -2
  18. data/motion-prime/api_client.rb +35 -36
  19. data/motion-prime/config/base.rb +0 -2
  20. data/motion-prime/core_ext/kernel.rb +2 -1
  21. data/motion-prime/elements/base_element.rb +7 -2
  22. data/motion-prime/elements/spinner.rb +7 -0
  23. data/motion-prime/elements/table_view.rb +7 -0
  24. data/motion-prime/helpers/has_search_bar.rb +11 -5
  25. data/motion-prime/models/_finder_mixin.rb +5 -12
  26. data/motion-prime/models/_nano_bag_mixin.rb +1 -1
  27. data/motion-prime/models/_sync_mixin.rb +52 -37
  28. data/motion-prime/screens/_base_mixin.rb +4 -0
  29. data/motion-prime/screens/_navigation_mixin.rb +3 -3
  30. data/motion-prime/screens/screen.rb +1 -1
  31. data/motion-prime/sections/base_section.rb +12 -12
  32. data/motion-prime/sections/form/base_field_section.rb +1 -1
  33. data/motion-prime/sections/form/date_field_section.rb +5 -0
  34. data/motion-prime/sections/form/password_field_section.rb +1 -1
  35. data/motion-prime/sections/form/string_field_section.rb +1 -1
  36. data/motion-prime/sections/form/text_field_section.rb +1 -1
  37. data/motion-prime/sections/table.rb +7 -0
  38. data/motion-prime/sections/table/table_delegate.rb +14 -4
  39. data/motion-prime/support/mp_spinner.rb +16 -0
  40. data/motion-prime/support/mp_table_view.rb +6 -0
  41. data/motion-prime/support/tab_bar_controller.rb +3 -3
  42. data/motion-prime/support/temp_fixes.rb +6 -0
  43. data/motion-prime/version.rb +1 -1
  44. data/motion-prime/views/layout.rb +2 -1
  45. data/motion-prime/views/view_builder.rb +1 -1
  46. metadata +24 -2
@@ -49,6 +49,13 @@
49
49
  </a>
50
50
  </li>
51
51
 
52
+
53
+ <li>
54
+ <a class="source" href="tables.html">
55
+ tables.rb
56
+ </a>
57
+ </li>
58
+
52
59
  </ol>
53
60
  </div>
54
61
 
@@ -49,6 +49,13 @@
49
49
  </a>
50
50
  </li>
51
51
 
52
+
53
+ <li>
54
+ <a class="source" href="tables.html">
55
+ tables.rb
56
+ </a>
57
+ </li>
58
+
52
59
  </ol>
53
60
  </div>
54
61
 
@@ -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>&quot;TableSection&quot; is a &quot;Section&quot; 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">&lt; <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">&lt; <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">&lt; <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&#39;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.6.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.3'
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.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("methadone")
30
- spec.add_dependency("rm-digest")
29
+ spec.add_dependency 'afmotion', '~> 2.0.0'
30
+ spec.add_dependency "methadone"
31
+ spec.add_dependency "rm-digest"
31
32
  end
@@ -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
- data = data.clone
10
- files = data.delete(:files)
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 + data.keys.map(&:to_s).sort.join
20
+ config.signature_secret + params.keys.map(&:to_s).sort.join
25
21
  )
26
- params[:payload].merge!(sign: signature)
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
- BW::HTTP.post("#{config.base}#{config.auth_path}", request_params(data)) do |response|
41
- body = response.body.to_s
42
- auth_data = if body.present?
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.status_code) if use_callback
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
- BW::HTTP.send method, api_url(path), request_params(params) do |response|
72
- if !response.ok? && options[:allow_queue] && config.allow_queue?
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
- json = parse_json(response.body.to_s)
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
@@ -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 Array.wrap(options[:except]).include?(ivar[1..-1])
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 'deallocating elemenet', self.name, self.to_s, view_class#, view.try(:to_s)
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
@@ -0,0 +1,7 @@
1
+ module MotionPrime
2
+ class SpinnerElement < BaseElement
3
+ def view_class
4
+ "MPSpinner"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module MotionPrime
2
+ class TableViewElement < BaseElement
3
+ def view_class
4
+ "MPTableView"
5
+ end
6
+ end
7
+ end
@@ -4,21 +4,27 @@ module MotionPrime
4
4
  def add_search_bar(options = {}, &block)
5
5
  target = options.delete(:target)
6
6
 
7
- search_bar = create_search_bar(options)
8
- search_bar.delegate = self
7
+ @_search_bar = create_search_bar(options)
8
+ @_search_bar.setDelegate self
9
9
 
10
10
  if target
11
- target.addSubview search_bar
11
+ target.addSubview @_search_bar
12
12
  elsif is_a?(TableSection)
13
- self.table_view.tableHeaderView = search_bar
13
+ self.table_view.tableHeaderView = @_search_bar
14
14
  end
15
15
 
16
16
  @search_callback = block
17
- search_bar
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(:name, NSFEqualTo, "Bob") # => [<User#1>]
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[1] && arg[2]
60
- # standard way to find
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
- options = {}
69
- sort_options = {}
62
+ raise "Please use Model#all to find all records."
70
63
  else
71
- raise "unexpected parameters #{arg}"
64
+ raise "Unexpected parameters: #{arg}."
72
65
  end
73
66
  search = NSFNanoSearch.searchWithStore(self.store)
74
67