Class: RubyMotionQuery::App

Inherits:
Object
  • Object
show all
Defined in:
lib/project/red_alert.rb,
lib/project/field_templates.rb,
lib/project/button_templates.rb

Constant Summary collapse

TEMPLATE_FIELD_STYLES =
[:input, :secure, :change_password, :login]
ALL_FIELD_STYLES =
TEMPLATE_FIELD_STYLES + [:custom]
ALERT_STYLES =
ALL_FIELD_STYLES + [:alert]
VALID_STYLES =
ALERT_STYLES + [:sheet]

Class Method Summary collapse

Class Method Details

.add_template_actions(template, &block) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/project/button_templates.rb', line 10

def self.add_template_actions(template, &block)
  yes    = "Yes" #NSLocalizedString("Yes", nil)
  no     = "No" #NSLocalizedString("No", nil)
  cancel = "Cancel" #NSLocalizedString("Cancel", nil)
  ok     = "OK" #NSLocalizedString("OK", nil)
  delete = "Delete" #NSLocalizedString("Delete", nil)

  case template
  when :yes_no
    [
      rmq.app.make_button(title: yes, tag: :yes, &block),
      rmq.app.make_button(title: no, tag: :no, &block)
    ]
  when :yes_no_cancel
    [
      rmq.app.make_button(title: yes, tag: :yes, &block),
      rmq.app.make_button(title: no, tag: :no, &block),
      rmq.app.make_button(title: cancel, tag: :cancel, style: :cancel, &block)
    ]
  when :ok_cancel
    [
      rmq.app.make_button(title: ok, &block),
      rmq.app.make_button(title: cancel, tag: :cancel, style: :cancel, &block)
    ]
  when :delete_cancel
    [
      rmq.app.make_button(title: delete, tag: :delete, style: :destructive, &block),
      rmq.app.make_button(title: cancel, tag: :cancel, style: :cancel, &block)
    ]
  else
    []
  end
end

.add_template_fieldset(template, opts = {}) ⇒ Object

When adding a new template do the following: 1 - Add it here 2 - Add the test 3 - Add symbol to the README.md list



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/project/field_templates.rb', line 9

def self.add_template_fieldset(template, opts={})

               = NSLocalizedString("Login", nil)
  password          = NSLocalizedString("Password", nil)
  current_password  = NSLocalizedString("Current Password", nil)
  new_password      = NSLocalizedString("New Password", nil)

  fieldset = {alert_view_style: UIAlertViewStyleDefault, fields: [] }
  case template
    when :input
      fieldset[:alert_view_style] = UIAlertViewStylePlainTextInput
      fieldset[:fields] =
      [
        rmq.app.make_field(:text, keyboard_type: :default, secure_text_entry: false, placeholder: opts.fetch(:placeholder,''))
      ]
    when :secure
      fieldset[:alert_view_style] = UIAlertViewStyleSecureTextInput
      fieldset[:fields] =
        [
          rmq.app.make_field(:text, keyboard_type: :default, secure_text_entry: true, placeholder: opts.fetch(:placeholder,''))
        ]
    when :login
      fieldset[:alert_view_style] = UIAlertViewStyleLoginAndPasswordInput
      fieldset[:fields] =
        [
          rmq.app.make_field(:login, keyboard_type: :email_address, secure_text_entry: false, placeholder: ),
          rmq.app.make_field(:password, keyboard_type: :default, secure_text_entry: true, placeholder: password)
        ]
    when :change_password
      fieldset[:alert_view_style] = UIAlertViewStyleLoginAndPasswordInput
      fieldset[:fields] =
        [
          rmq.app.make_field(:current_password, keyboard_type: :default, secure_text_entry: true, placeholder: current_password),
          rmq.app.make_field(:new_password, keyboard_type: :default, secure_text_entry: true, placeholder: new_password)
        ]
  end
  fieldset
end

.alert(opts = {}, &block) ⇒ UIAlertController

Creates and shows the UIAlertController (iOS 8) or UIAlertView/UIActionSheet (iOS 7). Usage Example:

rmq.app.alert(message: "This is a test")
rmq.app.alert(title: "Hey there", message: "Are you happy?")

Returns:



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/project/red_alert.rb', line 15

def alert(opts={}, &block)

  # ------------------------------------
  # -- Setup sane defaults -------------
  # ------------------------------------
  opts           = {message: opts} if opts.is_a? String
  opts           = {style: :alert, animated: true, show_now: true}.merge(opts)
		# Ability to make no message
  opts[:message] = if opts.has_key?(:message)
    opts[:message].nil? ? nil : opts[:message].to_s
  else
    NSLocalizedString("Alert!", nil)
  end


  opts[:style]   = VALID_STYLES.include?(opts[:style]) ? opts[:style] : :alert
  if opts[:style] == :sheet and rmq.device.ipad? and opts[:source].nil?
    raise ArgumentError.new "Please provide a :source view to use :sheet on iPad"
  end
  opts[:fields]  = opts[:style] == :custom && opts[:fields] ? opts[:fields] : {text: {placeholder: ''}}
  api            = rmq.device.ios_at_least?(8) ? :modern : :deprecated
  api            = :deprecated if rmq.device.ios_at_least?(8) && opts[:api] == :deprecated
  opts[:api]     = api


  # -----------------------------------------
  # -- Who provides the alerts? -------------
  # -----------------------------------------

  if opts[:api] == :modern
    provider = AlertControllerProvider.new
  else
    if ALERT_STYLES.include?(opts[:style])
      provider = AlertViewProvider.new
    else
      provider = ActionSheetProvider.new
    end
  end

  # -------------------------------------------------
  # -- Configure the input fields --------------
  # -------------------------------------------------

  fieldset = {alert_view_style: UIAlertViewStyleDefault, fields: []}

  if TEMPLATE_FIELD_STYLES.include?(opts[:style])
    fieldset = add_template_fieldset(opts[:style], opts)
  elsif opts[:style] == :custom
    fieldset = custom_fieldset(opts[:api], opts[:fields])
  end

  opts[:style] = :alert if ALL_FIELD_STYLES.include?(opts[:style])

  # -------------------------------------------------
  # -- Configure the actions (choices) --------------
  # -------------------------------------------------
  actions = []
  if opts[:actions] && opts[:actions].is_a?(Array) && opts[:actions].length > 0
    # caller has pre-defined actions
    actions << map_action_buttons(opts[:actions], &block)
  elsif opts[:actions] && opts[:actions].is_a?(Symbol)
    # caller wants a template
    actions << add_template_actions(opts[:actions], &block)
  elsif block_given?
    # convert our block into the one & only action
    button_text = NSLocalizedString("OK", nil) # Localized string failing
    button_text = "OK"
    actions << AlertAction.new(button_text, &block)
  else
    # NSLocalizedString causes crash if passed to AlertAction
    actions << [AlertAction.new]
  end
  provider.build(actions.flatten.compact, fieldset, opts)

  # --------------------------------------------
  # -- Show the modal right away? --------------
  # --------------------------------------------
  provider.show if opts[:show_now]

  # TODO: find a better way to do this ugly housekeeping... right now, this never gets cleaned, so this is leaky.
  if opts[:api] == :deprecated
    @rmq_red_alert_providers ||= []
    @rmq_red_alert_providers << provider
  end

  provider
end

.custom_fieldset(api_version = :modern, fields) ⇒ Object

alert



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/project/red_alert.rb', line 103

def custom_fieldset(api_version = :modern, fields)
  raise ArgumentError.new "At least one field must be provided for a custom style" unless fields && fields.count > 0
  fieldset = {alert_view_style: UIAlertViewStyleDefault, fields: [] }
  if api_version == :deprecated
    case fields.count
      when 1
        fieldset[:alert_view_style] = UIAlertViewStylePlainTextInput
      when 2
        fieldset[:alert_view_style] = UIAlertViewStyleLoginAndPasswordInput
      else
        raise ArgumentError.new "When running iOS < 8, up to two fields can be provided for a custom style"
    end
  end
  alert_fields = []
  fields.each do |k, v|
    alert_fields << AlertField.new(k, v)
  end
  fieldset[:fields] = alert_fields
  fieldset
end

.make_button(opts = {}, &block) ⇒ AlertAction

Returns an AlertAction from given parameters Usage Example:

yes = rmq.make_button("Yes")
cancel = rmq.make_button(title: "Cancel", style: :cancel) {
   puts "Cancel pressed"
}

Returns:



141
142
143
# File 'lib/project/red_alert.rb', line 141

def make_button(opts={}, &block)
  AlertAction.new(opts, &block)
end

.make_field(name, opts = {}) ⇒ AlertField

Returns an AlertField from given parameters Usage Example:

 = rmq.make_field("Login")
password = rmq.make_field(:password, secure: true, placeholder: 'Password')

Returns:



130
131
132
# File 'lib/project/red_alert.rb', line 130

def make_field(name, opts={})
  AlertField.new(name, opts)
end

.map_action_buttons(buttons, &block) ⇒ Object

Returns an array of action buttons based on the symbols you pass in. Usage Example:

rmq.app.alert title: "Hey!", actions: [ "Go ahead", :cancel, :delete ] do |button_tag|
  puts "#{button_text} pressed"
end


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/project/red_alert.rb', line 150

def map_action_buttons(buttons, &block)
  yes    = NSLocalizedString("Yes", nil)
  no     = NSLocalizedString("No", nil)
  cancel = NSLocalizedString("Cancel", nil)
  ok     = NSLocalizedString("OK", nil)
  delete = NSLocalizedString("Delete", nil)

  buttons.map do |button|
    case button
    when :cancel  then make_button(title: cancel, tag: :cancel, style: :cancel, &block)
    when :yes     then make_button(title: yes, tag: :yes, &block)
    when :no      then make_button(title: no, tag: :no, &block)
    when :ok      then make_button(title: ok, tag: :ok, &block)
    when :delete  then make_button(title: delete, tag: :delete, style: :destructive, &block)
    when String   then make_button(title: button, tag: button, &block)
    else button
    end
  end
end