ruby_native 0.10.6 → 0.10.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0704fd207fd1ac26e9d3a39472bf7d87d864a793e7a2aa31725e3255caae4299
4
- data.tar.gz: c2a5d06c063a3cf9bb1b3a7f4c446485aac8b5e3848d47fddf8133e04ec062be
3
+ metadata.gz: 1020516eb9b684247d40d16d00153a75691082fbe9a3e769d552826d7a217135
4
+ data.tar.gz: cf8a1600e15ae4a7b26767b14543c763d13421aa96187e75a0608734e9780cab
5
5
  SHA512:
6
- metadata.gz: f27087c2df549ec0f2ef9fad1d8e83a21ded83a160e074fa636b750a544d698fd836d46ed10b41859d638ae344330efd4267b64300d1b85c850c381b43f433c2
7
- data.tar.gz: cb66d64470ea7820bc6aa58f31b64bb7b716440d3fd898a90d47b44c3671382540712076f1266ceebbfe5575564435dc6f9c027df692eacf1cc334a6d3131db0
6
+ metadata.gz: 7dceda118ad0c65f7508a1d77ce5f9a77b0fbbd59d1137673d4076b987ccadc7311135dc0003cbe873747ecfea8b1a4838c69828364b3b56d724b71e3d236dee
7
+ data.tar.gz: '0528af6b54e2bc22abc87c6f24d5b1d470872c5abb3d0bb3f0ad8ce93fe0d4657514938e322a5cec578b7982fb827ac0c500fedbac0037fb32bfc047899597d1'
@@ -3,7 +3,7 @@ module RubyNative
3
3
  def show
4
4
  RubyNative.load_config if Rails.env.local?
5
5
  response.set_header("X-Ruby-Native-Version", RubyNative::VERSION)
6
- render json: RubyNative.config
6
+ render json: RubyNative.config_as_json
7
7
  end
8
8
  end
9
9
  end
@@ -126,6 +126,22 @@ module RubyNative
126
126
  end
127
127
  end
128
128
 
129
+ # Adds a native share button to the nav bar. Tapping it opens the
130
+ # platform share sheet for `url:` (defaults to the current page on the
131
+ # web side) so it works even where embedded web views don't support
132
+ # `navigator.share`. Icons follow the same rules as the other navbar
133
+ # buttons: `icon:` applies to every platform and `icons:` ({ ios:,
134
+ # android: }) overrides per platform.
135
+ def share_button(url: nil, title: "Share", icon: "square.and.arrow.up", icons: nil, position: :trailing)
136
+ resolved = RubyNative::Helper.resolve_icon(icon: icon, icons: icons, platform: @context.try(:native_platform))
137
+ data = { native_button: "", native_share: "" }
138
+ data[:native_title] = title if title
139
+ data[:native_icon] = resolved if resolved
140
+ data[:native_position] = position.to_s
141
+ data[:native_share_url] = url if url
142
+ @items << @context.tag.div(data: data)
143
+ end
144
+
129
145
  def submit_button(title: "Save", click: "[type='submit']")
130
146
  @items << @context.tag.div(data: {
131
147
  native_submit_button: "",
@@ -155,6 +171,19 @@ module RubyNative
155
171
  @items << @context.tag.div(data: data)
156
172
  end
157
173
 
174
+ # Adds a share entry to a navbar button's dropdown menu. Selecting it
175
+ # opens the platform share sheet for `url:` (defaults to the current
176
+ # page on the web side). Icons follow the same `icon:`/`icons:` rules
177
+ # as the other menu items.
178
+ def share_item(title = "Share", url: nil, icon: "square.and.arrow.up", icons: nil, selected: false)
179
+ resolved = RubyNative::Helper.resolve_icon(icon: icon, icons: icons, platform: @context.try(:native_platform))
180
+ data = { native_menu_item: "", native_title: title, native_share: "" }
181
+ data[:native_share_url] = url if url
182
+ data[:native_icon] = resolved if resolved
183
+ data[:native_selected] = "" if selected
184
+ @items << @context.tag.div(data: data)
185
+ end
186
+
158
187
  def to_html
159
188
  @context.safe_join(@items)
160
189
  end
@@ -1,3 +1,3 @@
1
1
  module RubyNative
2
- VERSION = "0.10.6"
2
+ VERSION = "0.10.9"
3
3
  end
data/lib/ruby_native.rb CHANGED
@@ -43,6 +43,7 @@ module RubyNative
43
43
  self.config[:auth] ||= {}
44
44
  normalize_oauth_paths
45
45
  backfill_tab_icons
46
+ backfill_error_icons
46
47
  end
47
48
 
48
49
  # Mirrors per-platform `icons:` into the legacy flat `icon:` field so native
@@ -59,6 +60,86 @@ module RubyNative
59
60
  end
60
61
  end
61
62
 
63
+ # Mirrors `backfill_tab_icons` for the error screen: fills a state's flat
64
+ # `icon` from its per-platform `icons` (ios first, then android), so the iOS
65
+ # app, which reads only the flat `icon`, still renders one. An explicit
66
+ # `icon:` wins.
67
+ def self.backfill_error_icons
68
+ errors = self.config[:errors]
69
+ return unless errors.is_a?(Hash)
70
+
71
+ ERROR_SCREEN_STATES.each do |state|
72
+ state_config = errors[state]
73
+ next unless state_config.is_a?(Hash)
74
+
75
+ icons = state_config[:icons]
76
+ next unless icons.is_a?(Hash)
77
+
78
+ state_config[:icon] ||= icons[:ios] || icons[:android]
79
+ end
80
+ end
81
+
82
+ # The native fallback screen has two states: `offline` (no connectivity) and
83
+ # `generic` (any other load failure). Each can carry a per-platform icon and
84
+ # localized copy.
85
+ ERROR_SCREEN_STATES = %i[offline generic].freeze
86
+ ERROR_SCREEN_COPY_KEYS = %i[title message].freeze
87
+
88
+ # The JSON served at GET /native/config. Identical to `config`, except the
89
+ # `errors` block is enriched: per-state icons from config/ruby_native.yml are
90
+ # merged with localized title/message pulled from the host app's I18n
91
+ # (`ruby_native.errors.<state>.<key>`), one entry per available locale. Only
92
+ # values the developer actually provided are emitted; the native apps fall
93
+ # back to bundled English copy for anything missing. Built on a deep copy so
94
+ # the in-memory `config` the server reads for view helpers is never mutated.
95
+ def self.config_as_json
96
+ return config if config.nil?
97
+
98
+ payload = config.deep_dup
99
+ errors = error_screen_config(payload[:errors])
100
+ if errors.empty?
101
+ payload.delete(:errors)
102
+ else
103
+ payload[:errors] = errors
104
+ end
105
+ payload
106
+ end
107
+
108
+ # Merges per-state error-screen icons (from YAML) with localized copy (from
109
+ # I18n) into the shape the native apps decode. Omits any state with neither an
110
+ # icon nor copy, so an untouched app sends no `errors` block at all.
111
+ def self.error_screen_config(yaml_errors)
112
+ config = ERROR_SCREEN_STATES.each_with_object({}) do |state, result|
113
+ entry = {}
114
+ state_config = yaml_errors[state] if yaml_errors.is_a?(Hash)
115
+ if state_config.is_a?(Hash)
116
+ entry[:icon] = state_config[:icon] if state_config[:icon]
117
+ entry[:icons] = state_config[:icons] if state_config[:icons]
118
+ end
119
+ ERROR_SCREEN_COPY_KEYS.each do |key|
120
+ translations = error_screen_translations("#{state}.#{key}")
121
+ entry[key] = translations unless translations.empty?
122
+ end
123
+ result[state] = entry unless entry.empty?
124
+ end
125
+
126
+ # The Retry button label is shared by both states, so it sits at the top of
127
+ # the block rather than under a state.
128
+ retry_label = error_screen_translations("retry")
129
+ config[:retry] = retry_label unless retry_label.empty?
130
+ config
131
+ end
132
+
133
+ # Reads `ruby_native.errors.<subkey>` for every available locale, keeping only
134
+ # the locales the developer actually translated. Copy lives in the host app's
135
+ # own locale files; the gem ships none.
136
+ def self.error_screen_translations(subkey)
137
+ I18n.available_locales.each_with_object({}) do |locale, result|
138
+ value = I18n.t("ruby_native.errors.#{subkey}", locale: locale, default: nil)
139
+ result[locale] = value unless value.nil?
140
+ end
141
+ end
142
+
62
143
  # `auth.oauth_paths` must list only OAuth authorize paths, never their
63
144
  # callbacks. The native app treats every listed path as a sign-in trigger and
64
145
  # derives the provider from the last path segment, so a callback entry like
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_native
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.6
4
+ version: 0.10.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Masilotti