glimmer-dsl-opal 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.13.0
1
+ 0.14.0
@@ -56,6 +56,7 @@ if RUBY_ENGINE == 'opal'
56
56
  # require 'glimmer-dsl-opal/vendor/jquery-ui/jquery-ui.theme.min.css'
57
57
  require 'opal-jquery'
58
58
  require 'opal/jquery/local_storage'
59
+ require 'promise'
59
60
 
60
61
  require 'facets/hash/symbolize_keys'
61
62
  require 'glimmer-dsl-opal/ext/class'
@@ -0,0 +1,157 @@
1
+ # Copyright (c) 2020-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'net/http'
23
+ require 'json'
24
+ require 'facets/string/titlecase'
25
+
26
+ class Weather
27
+ include Glimmer::UI::CustomShell
28
+
29
+ DEFAULT_FONT_HEIGHT = 30
30
+ DEFAULT_FOREGROUND = :white
31
+ DEFAULT_BACKGROUND = rgb(135, 176, 235)
32
+
33
+ attr_accessor :city, :temp, :temp_min, :temp_max, :feels_like, :humidity
34
+
35
+ before_body {
36
+ @weather_mutex = Mutex.new
37
+ self.city = 'Montreal, QC, CA'
38
+ fetch_weather!
39
+ }
40
+
41
+ body {
42
+ shell(:no_resize) {
43
+ grid_layout
44
+
45
+ text 'Glimmer Weather'
46
+ minimum_size 400, 300
47
+ background DEFAULT_BACKGROUND
48
+
49
+ text {
50
+ layout_data(:center, :center, true, true)
51
+
52
+ text <=> [self, :city]
53
+
54
+ on_key_pressed {|event|
55
+ if event.keyCode == swt(:cr) # carriage return
56
+ Thread.new do
57
+ fetch_weather!
58
+ end
59
+ end
60
+ }
61
+ }
62
+
63
+ tab_folder {
64
+ layout_data(:center, :center, true, true)
65
+
66
+ ['℃', '℉'].each do |temp_unit|
67
+ tab_item {
68
+ grid_layout 2, false
69
+
70
+ text temp_unit
71
+ background DEFAULT_BACKGROUND
72
+
73
+ rectangle(0, 0, [:default, -2], [:default, -2], 15, 15) {
74
+ foreground DEFAULT_FOREGROUND
75
+ }
76
+
77
+ %w[temp temp_min temp_max feels_like].each do |field_name|
78
+ temp_field(field_name, temp_unit)
79
+ end
80
+
81
+ humidity_field
82
+ }
83
+ end
84
+ }
85
+ }
86
+ }
87
+
88
+ def temp_field(field_name, temp_unit)
89
+ name_label(field_name)
90
+ label {
91
+ layout_data(:fill, :center, true, false)
92
+ text <= [self, field_name, on_read: ->(t) { "#{kelvin_to_temp_unit(t, temp_unit).to_f.round}°" }]
93
+ font height: DEFAULT_FONT_HEIGHT
94
+ foreground DEFAULT_FOREGROUND
95
+ }
96
+ end
97
+
98
+ def humidity_field
99
+ name_label('humidity')
100
+ label {
101
+ layout_data(:fill, :center, true, false)
102
+ text <= [self, 'humidity', on_read: ->(h) { "#{h.to_f.round}%" }]
103
+ font height: DEFAULT_FONT_HEIGHT
104
+ foreground DEFAULT_FOREGROUND
105
+ }
106
+ end
107
+
108
+ def name_label(field_name)
109
+ label {
110
+ layout_data :fill, :center, false, false
111
+ text field_name.titlecase
112
+ font height: DEFAULT_FONT_HEIGHT
113
+ foreground DEFAULT_FOREGROUND
114
+ }
115
+ end
116
+
117
+ def fetch_weather!
118
+ @weather_mutex.synchronize do
119
+ self.weather_data = JSON.parse(Net::HTTP.get('api.openweathermap.org', "/data/2.5/weather?q=#{city}&appid=1d16d70a9aec3570b5cbd27e6b421330"))
120
+ end
121
+ rescue => e
122
+ Glimmer::Config.logger.error "Unable to fetch weather due to error: #{e.full_message}"
123
+ end
124
+
125
+ def weather_data=(data)
126
+ @weather_data = data
127
+ main_data = data['main']
128
+ # temps come back in Kelvin
129
+ self.temp = main_data['temp']
130
+ self.temp_min = main_data['temp_min']
131
+ self.temp_max = main_data['temp_max']
132
+ self.feels_like = main_data['feels_like']
133
+ self.humidity = main_data['humidity']
134
+ end
135
+
136
+ def kelvin_to_temp_unit(kelvin, temp_unit)
137
+ temp_unit == '℃' ? kelvin_to_celsius(kelvin) : kelvin_to_fahrenheit(kelvin)
138
+ end
139
+
140
+ def kelvin_to_celsius(kelvin)
141
+ return nil if kelvin.nil?
142
+ kelvin - 273.15
143
+ end
144
+
145
+ def celsius_to_fahrenheit(celsius)
146
+ return nil if celsius.nil?
147
+ (celsius * 9 / 5 ) + 32
148
+ end
149
+
150
+ def kelvin_to_fahrenheit(kelvin)
151
+ return nil if kelvin.nil?
152
+ celsius_to_fahrenheit(kelvin_to_celsius(kelvin))
153
+ end
154
+
155
+ end
156
+
157
+ Weather.launch
@@ -20,15 +20,15 @@
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  class HelloButton
23
- include Glimmer
23
+ include Glimmer::UI::CustomShell
24
24
 
25
25
  attr_accessor :count
26
26
 
27
- def initialize
27
+ before_body {
28
28
  @count = 0
29
- end
29
+ }
30
30
 
31
- def launch
31
+ body {
32
32
  shell {
33
33
  text 'Hello, Button!'
34
34
 
@@ -39,8 +39,8 @@ class HelloButton
39
39
  self.count += 1
40
40
  }
41
41
  }
42
- }.open
43
- end
42
+ }
43
+ }
44
44
  end
45
45
 
46
- HelloButton.new.launch
46
+ HelloButton.launch
@@ -19,45 +19,47 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
- class Person
23
- attr_accessor :country, :country_options
24
-
25
- def initialize
26
- self.country_options = ['', 'Canada', 'US', 'Mexico']
27
- reset_country
28
- end
29
-
30
- def reset_country
31
- self.country = 'Canada'
22
+ class HelloCombo
23
+ class Person
24
+ attr_accessor :country, :country_options
25
+
26
+ def initialize
27
+ self.country_options = ['', 'Canada', 'US', 'Mexico']
28
+ reset_country!
29
+ end
30
+
31
+ def reset_country!
32
+ self.country = 'Canada'
33
+ end
32
34
  end
33
- end
34
35
 
35
- class HelloCombo
36
- include Glimmer
36
+ include Glimmer::UI::CustomShell
37
37
 
38
- def launch
39
- person = Person.new
40
-
38
+ before_body {
39
+ @person = Person.new
40
+ }
41
+
42
+ body {
41
43
  shell {
42
44
  row_layout(:vertical) {
43
- pack false
45
+ fill true
44
46
  }
45
47
 
46
48
  text 'Hello, Combo!'
47
49
 
48
50
  combo(:read_only) {
49
- selection <=> [person, :country]
51
+ selection <=> [@person, :country] # also binds to country_options by convention
50
52
  }
51
53
 
52
54
  button {
53
55
  text 'Reset Selection'
54
56
 
55
57
  on_widget_selected do
56
- person.reset_country
58
+ @person.reset_country!
57
59
  end
58
60
  }
59
- }.open
60
- end
61
+ }
62
+ }
61
63
  end
62
64
 
63
- HelloCombo.new.launch
65
+ HelloCombo.launch
@@ -19,20 +19,38 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
- require_relative 'hello_computed/contact'
23
-
24
22
  class HelloComputed
25
- include Glimmer
23
+ class Contact
24
+ attr_accessor :first_name, :last_name, :year_of_birth
25
+
26
+ def initialize(attribute_map)
27
+ @first_name = attribute_map[:first_name]
28
+ @last_name = attribute_map[:last_name]
29
+ @year_of_birth = attribute_map[:year_of_birth]
30
+ end
31
+
32
+ def name
33
+ "#{last_name}, #{first_name}"
34
+ end
35
+
36
+ def age
37
+ Time.now.year - year_of_birth.to_i
38
+ rescue
39
+ 0
40
+ end
41
+ end
42
+
43
+ include Glimmer::UI::CustomShell
26
44
 
27
- def initialize
45
+ before_body {
28
46
  @contact = Contact.new(
29
47
  first_name: 'Barry',
30
48
  last_name: 'McKibbin',
31
49
  year_of_birth: 1985
32
50
  )
33
- end
51
+ }
34
52
 
35
- def launch
53
+ body {
36
54
  shell {
37
55
  text 'Hello, Computed!'
38
56
 
@@ -89,8 +107,8 @@ class HelloComputed
89
107
  }
90
108
  }
91
109
  }
92
- }.open
93
- end
110
+ }
111
+ }
94
112
  end
95
113
 
96
- HelloComputed.new.launch
114
+ HelloComputed.launch
data/lib/net/http.rb CHANGED
@@ -19,8 +19,6 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
- # Missing Net module class methods TODO implement
23
-
24
22
  require_relative '../uri'
25
23
 
26
24
  module Net
@@ -30,11 +28,21 @@ module Net
30
28
  class HTTP
31
29
  class << self
32
30
  def post_form(uri, params)
33
- response_body = nil
34
- result = ::HTTP.post(uri, payload: params) do |response|
35
- response_body = response.body
31
+ uri = "#{`window.location.protocol`}//#{File.join(uri)}" unless uri.start_with?('http:') || uri.start_with?('https:') # TODO refactor repetitive code
32
+ result = nil
33
+ ::HTTP.post(uri, {async: false, dataType: 'text', data: params}) do |response|
34
+ result = response.body if response.ok?
35
+ end
36
+ result
37
+ end
38
+
39
+ def get(uri, path_and_params)
40
+ uri = "#{`window.location.protocol`}//#{File.join(uri, path_and_params)}" unless uri.start_with?('http:') || uri.start_with?('https:') # TODO refactor repetitive code
41
+ result = nil
42
+ ::HTTP.get(uri, {async: false, dataType: 'text'}) do |response|
43
+ result = response.body if response.ok?
36
44
  end
37
- response_body
45
+ result
38
46
  end
39
47
  end
40
48
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-opal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-10 00:00:00.000000000 Z
11
+ date: 2021-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -278,13 +278,13 @@ files:
278
278
  - lib/glimmer-dsl-opal/samples/elaborate/tic_tac_toe.rb
279
279
  - lib/glimmer-dsl-opal/samples/elaborate/tic_tac_toe/board.rb
280
280
  - lib/glimmer-dsl-opal/samples/elaborate/tic_tac_toe/cell.rb
281
+ - lib/glimmer-dsl-opal/samples/elaborate/weather.rb
281
282
  - lib/glimmer-dsl-opal/samples/hello/hello_browser.rb
282
283
  - lib/glimmer-dsl-opal/samples/hello/hello_button.rb
283
284
  - lib/glimmer-dsl-opal/samples/hello/hello_checkbox.rb
284
285
  - lib/glimmer-dsl-opal/samples/hello/hello_checkbox_group.rb
285
286
  - lib/glimmer-dsl-opal/samples/hello/hello_combo.rb
286
287
  - lib/glimmer-dsl-opal/samples/hello/hello_computed.rb
287
- - lib/glimmer-dsl-opal/samples/hello/hello_computed/contact.rb
288
288
  - lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb
289
289
  - lib/glimmer-dsl-opal/samples/hello/hello_custom_widget.rb
290
290
  - lib/glimmer-dsl-opal/samples/hello/hello_date_time.rb
@@ -1,42 +0,0 @@
1
- # Copyright (c) 2020-2021 Andy Maleh
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the
5
- # "Software"), to deal in the Software without restriction, including
6
- # without limitation the rights to use, copy, modify, merge, publish,
7
- # distribute, sublicense, and/or sell copies of the Software, and to
8
- # permit persons to whom the Software is furnished to do so, subject to
9
- # the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be
12
- # included in all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
-
22
- class HelloComputed
23
- class Contact
24
- attr_accessor :first_name, :last_name, :year_of_birth
25
-
26
- def initialize(attribute_map)
27
- @first_name = attribute_map[:first_name]
28
- @last_name = attribute_map[:last_name]
29
- @year_of_birth = attribute_map[:year_of_birth]
30
- end
31
-
32
- def name
33
- "#{last_name}, #{first_name}"
34
- end
35
-
36
- def age
37
- Time.now.year - year_of_birth.to_i
38
- rescue
39
- 0
40
- end
41
- end
42
- end