glib-web 3.12.0 → 3.14.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 +4 -4
- data/app/channels/glib/channel/appearance_channel.rb +28 -0
- data/app/channels/glib/channel/chat_channel.rb +16 -0
- data/app/controllers/concerns/glib/json/libs.rb +105 -9
- data/app/controllers/concerns/glib/json/ui.rb +1 -1
- data/app/controllers/glib/home_controller.rb +20 -0
- data/app/helpers/glib/json_ui/action_builder/dialogs.rb +1 -0
- data/app/helpers/glib/json_ui/action_builder/fields.rb +8 -0
- data/app/helpers/glib/json_ui/action_builder.rb +15 -0
- data/app/helpers/glib/json_ui/page_helper.rb +21 -0
- data/app/helpers/glib/json_ui/view_builder/fields.rb +10 -0
- data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +14 -0
- data/app/views/json_ui/garage/actions/_dialogs_show.json.jbuilder +4 -1
- data/app/views/json_ui/garage/empty.json.jbuilder +3 -0
- data/app/views/json_ui/garage/forms/dialogs_close.json.jbuilder +14 -0
- data/app/views/json_ui/garage/forms/dialogs_update.json.jbuilder +12 -0
- data/app/views/json_ui/garage/forms/dirty_prompt.json.jbuilder +0 -1
- data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +12 -0
- data/app/views/json_ui/garage/notifications/action_cable.json.jbuilder +54 -100
- data/app/views/layouts/json_ui/no_custom.html.erb +5 -0
- data/app/views/layouts/json_ui/renderer.html.erb +0 -2
- data/config/routes.rb +1 -0
- data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +3 -3
- data/lib/glib/json_crawler/http.rb +2 -3
- metadata +8 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33411954512fada9329818d4e011f5cb70f9c528a034fd87b8737318af18e07d
|
4
|
+
data.tar.gz: 492020f2693abdd8ffc38334c771cbe550952044f3030f9221fe163c5c49b103
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97d3edb87b4e25bb71318dea8dd8243a2f98be27f74ac612e135100bfb5b12317c2b39e763f4e1301c2e3c08736fa7411f91a5a37eea96e1148b0d9d0e1e9841
|
7
|
+
data.tar.gz: 032b11ef90b8b22768459248da39de1a16f6342940cd902974bc96dc7d5a7c11acd7797d599e14bf21b11979b4ed237c053f9d82855856f29a7453b4f6ae98c4
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Glib
|
2
|
+
module Channel
|
3
|
+
class AppearanceChannel < ApplicationCable::Channel
|
4
|
+
def subscribed
|
5
|
+
stream_for "appearance_#{params[:room]}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def status(data)
|
9
|
+
action = {
|
10
|
+
action: 'labels/set',
|
11
|
+
targetId: 'label-1',
|
12
|
+
text: data['text']
|
13
|
+
# onSet: {
|
14
|
+
# action: 'timeouts/set',
|
15
|
+
# interval: 1000,
|
16
|
+
# onTimeout: {
|
17
|
+
# action: 'labels/set',
|
18
|
+
# targetId: 'label-1',
|
19
|
+
# text: "Room ##{data['room'].upcase}"
|
20
|
+
# }
|
21
|
+
# }
|
22
|
+
}
|
23
|
+
|
24
|
+
broadcast_to("appearance_#{data['room']}", action)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Glib
|
2
|
+
module Channel
|
3
|
+
class ChatChannel < ApplicationCable::Channel
|
4
|
+
rescue_from StandardError, with: :report_error
|
5
|
+
|
6
|
+
def subscribed
|
7
|
+
stream_for "chat_#{params[:room]}"
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def report_error(e)
|
12
|
+
# Rollbar.error(e)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -6,6 +6,8 @@ module Glib::Json::Libs
|
|
6
6
|
|
7
7
|
helper_method :json_ui_app_bundle_id, :json_ui_app_build_version, :json_ui_app_device_os
|
8
8
|
helper_method :json_ui_app_is_android?, :json_ui_app_is_ios?, :json_ui_app_is_web?
|
9
|
+
helper_method :json_ui_redirect_back_or_to
|
10
|
+
|
9
11
|
end
|
10
12
|
|
11
13
|
def json_ui_app_bundle_id
|
@@ -58,7 +60,7 @@ module Glib::Json::Libs
|
|
58
60
|
JSON.parse(render_to_string(template, locals: args))
|
59
61
|
end
|
60
62
|
|
61
|
-
def
|
63
|
+
def glib_redirect_to(url)
|
62
64
|
respond_to do |format|
|
63
65
|
format.html do
|
64
66
|
redirect_to url
|
@@ -75,11 +77,30 @@ module Glib::Json::Libs
|
|
75
77
|
end
|
76
78
|
end
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
+
# The behaviour provided by this convenience method assumes that user is logged in.
|
81
|
+
# When accessing a forbidden page, redirects to `user_default_url` because we don't
|
82
|
+
# want the user to get confused in the scenario where after logging in,
|
83
|
+
# glib_redirect_back_or_to tries to open a page that the user doesn't have access of.
|
84
|
+
def glib_handle_403(user_default_url)
|
85
|
+
respond_to do |format|
|
86
|
+
format.html do
|
87
|
+
redirect_to user_default_url
|
88
|
+
end
|
89
|
+
format.json do
|
90
|
+
render json: if glib_json_dialog_mode?
|
91
|
+
{ onLoad: __glib_error_dialog('Access denied', "Make sure you're logged in with the correct account.") }
|
92
|
+
else
|
93
|
+
{
|
94
|
+
onResponse: {
|
95
|
+
action: 'windows/open', url: user_default_url
|
96
|
+
}
|
97
|
+
}
|
98
|
+
end, status: Rails.env.test? ? :forbidden : :ok
|
99
|
+
end
|
100
|
+
end
|
80
101
|
end
|
81
102
|
|
82
|
-
def
|
103
|
+
def glib_handle_404
|
83
104
|
raise ActionController::RoutingError.new('Not Found')
|
84
105
|
|
85
106
|
# if json_ui_activated?
|
@@ -89,6 +110,69 @@ module Glib::Json::Libs
|
|
89
110
|
# end
|
90
111
|
end
|
91
112
|
|
113
|
+
REDIRECT_BACK_KEY = :glib_return_to_url
|
114
|
+
|
115
|
+
def glib_handle_401(sign_in_url)
|
116
|
+
if !glib_json_dialog_mode? && request.get?
|
117
|
+
session[REDIRECT_BACK_KEY] = url_for(params.to_unsafe_h.merge(format: nil))
|
118
|
+
end
|
119
|
+
|
120
|
+
respond_to do |format|
|
121
|
+
format.html do
|
122
|
+
redirect_to sign_in_url
|
123
|
+
end
|
124
|
+
format.json do
|
125
|
+
render json: {
|
126
|
+
# Handle dialogs_open and windows_open
|
127
|
+
glib_json_dialog_mode? ? :onLoad : :onResponse => __glib_error_dialog(
|
128
|
+
'Your session has ended', 'Please refresh the page and re-login.')
|
129
|
+
}, status: Rails.env.test? ? :unauthorized : :ok
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def __delete_redirect_back_url(url)
|
135
|
+
redirect_url = session.delete(REDIRECT_BACK_KEY) || url
|
136
|
+
end
|
137
|
+
|
138
|
+
def glib_redirect_back_or_to(url)
|
139
|
+
redirect_url = __delete_redirect_back_url(url)
|
140
|
+
glib_redirect_to redirect_url
|
141
|
+
end
|
142
|
+
|
143
|
+
def json_ui_redirect_back_or_to(url, json_action)
|
144
|
+
redirect_url = __delete_redirect_back_url(url)
|
145
|
+
json_action.windows_closeAll onClose: ->(subaction) do
|
146
|
+
subaction.windows_open url: redirect_url
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def glib_json_dialog_mode?
|
151
|
+
params[:_dialog].present? # E.g. _dialog=v1
|
152
|
+
end
|
153
|
+
|
154
|
+
def __glib_error_dialog(title, message)
|
155
|
+
{
|
156
|
+
action: 'dialogs/show',
|
157
|
+
# Don't show another dialog, just use the current one since it's a new dialog anyway, which means
|
158
|
+
# that it wouldn't contain existing user data.
|
159
|
+
updateExisting: glib_json_dialog_mode?,
|
160
|
+
title: title,
|
161
|
+
body: {
|
162
|
+
childViews: [
|
163
|
+
{
|
164
|
+
"view": "label",
|
165
|
+
"text": message
|
166
|
+
},
|
167
|
+
],
|
168
|
+
"padding": {
|
169
|
+
"x": 20,
|
170
|
+
"y": 22,
|
171
|
+
},
|
172
|
+
}
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
92
176
|
def glib_json_handle_500(exception)
|
93
177
|
if json_ui_activated? && Rails.env.production?
|
94
178
|
Rollbar.error(exception, :use_exception_level_filters => true) if defined?(Rollbar)
|
@@ -129,7 +213,7 @@ module Glib::Json::Libs
|
|
129
213
|
after_action :__json_traversal_register_dynamic_text
|
130
214
|
end
|
131
215
|
|
132
|
-
def json_libs_skip_json_ui(options)
|
216
|
+
def json_libs_skip_json_ui(options = {})
|
133
217
|
prepend_before_action options do
|
134
218
|
params[:_skip_render] = 'true'
|
135
219
|
end
|
@@ -152,13 +236,25 @@ module Glib::Json::Libs
|
|
152
236
|
rescue_from ActionController::InvalidAuthenticityToken do |exception|
|
153
237
|
sign_out(:user)
|
154
238
|
|
239
|
+
# respond_to do |format|
|
240
|
+
# format.json do
|
241
|
+
# render json: {
|
242
|
+
# onResponse: {
|
243
|
+
# action: 'windows/open-v1',
|
244
|
+
# url: url
|
245
|
+
# }
|
246
|
+
# }
|
247
|
+
# end
|
248
|
+
# end
|
249
|
+
|
155
250
|
respond_to do |format|
|
251
|
+
format.html do
|
252
|
+
redirect_to sign_in_url
|
253
|
+
end
|
156
254
|
format.json do
|
157
255
|
render json: {
|
158
|
-
|
159
|
-
|
160
|
-
url: root_url
|
161
|
-
}
|
256
|
+
glib_json_dialog_mode? ? :onLoad : :onResponse => __glib_error_dialog(
|
257
|
+
'Your session has expired', 'Please refresh the page and retry.')
|
162
258
|
}
|
163
259
|
end
|
164
260
|
end
|
@@ -81,7 +81,7 @@ module Glib::Json::Ui
|
|
81
81
|
|
82
82
|
private
|
83
83
|
def __json_ui_vue(hash, options)
|
84
|
-
renderer_path = options[:renderer_path]
|
84
|
+
renderer_path = params[:_skip_custom_render] == 'true' ? 'layouts/json_ui/no_custom' : options[:renderer_path]
|
85
85
|
@__json_ui_orig_page = response.body
|
86
86
|
response.body = render_to_string(
|
87
87
|
template: renderer_path,
|
@@ -1,5 +1,9 @@
|
|
1
1
|
module Glib
|
2
2
|
class HomeController < ApplicationController
|
3
|
+
prepend_before_action do
|
4
|
+
params[:_skip_custom_render] = 'true' if params[:custom_render] != 'true'
|
5
|
+
end
|
6
|
+
|
3
7
|
if try(:glib_auth_inited?)
|
4
8
|
skip_before_action :glib_load_resource
|
5
9
|
skip_before_action :glib_authorize_resource
|
@@ -35,6 +39,22 @@ module Glib
|
|
35
39
|
render path
|
36
40
|
end
|
37
41
|
|
42
|
+
def chat
|
43
|
+
chat_params = params[:chat]
|
44
|
+
|
45
|
+
payload = {
|
46
|
+
action: 'lists/append',
|
47
|
+
targetId: 'list-1',
|
48
|
+
row: {
|
49
|
+
template: 'thumbnail', title: chat_params[:user], subtitle: chat_params[:body]
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
Glib::Channel::ChatChannel.broadcast_to("chat_#{chat_params[:room]}", payload)
|
54
|
+
|
55
|
+
render template: 'json_ui/garage/empty'
|
56
|
+
end
|
57
|
+
|
38
58
|
def init_orders
|
39
59
|
@order_headings = {}
|
40
60
|
@orders = params[:orders] || []
|
@@ -124,6 +124,21 @@ module Glib
|
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
|
+
module Labels
|
128
|
+
class Set < Action
|
129
|
+
string :targetId
|
130
|
+
string :text
|
131
|
+
action :onSet
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
module Lists
|
136
|
+
class Append < Action
|
137
|
+
string :targetId
|
138
|
+
hash :row
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
127
142
|
# FUTURE
|
128
143
|
module Data
|
129
144
|
class Save < Action
|
@@ -10,6 +10,15 @@ module Glib
|
|
10
10
|
)
|
11
11
|
end
|
12
12
|
|
13
|
+
def glib_chat_url(options = {})
|
14
|
+
Glib::Web::Engine.routes.url_helpers.chat_url(options.merge(
|
15
|
+
protocol: request.protocol,
|
16
|
+
host: request.host,
|
17
|
+
port: request.port,
|
18
|
+
_render: params[:_render], format: params[:format])
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
13
22
|
def json_ui_garage_current_url(options = {})
|
14
23
|
json_ui_garage_url(options.merge(path: params[:path]))
|
15
24
|
end
|
@@ -89,6 +98,18 @@ module Glib
|
|
89
98
|
# @generic_content_builder = GenericBuilders::Content.new(json, self, @view_builder)
|
90
99
|
end
|
91
100
|
|
101
|
+
def actionCable(options = {})
|
102
|
+
json.actionCable do
|
103
|
+
if (on_error = options[:onError])
|
104
|
+
json.onError do
|
105
|
+
on_error.call(@action_builder)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
json.channels options[:channels]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
92
113
|
def content_builder(panelNames)
|
93
114
|
# NOTE: Can potentially be cached
|
94
115
|
builder = GenericBuilders::Content.new(json, self, @view_builder)
|
@@ -263,6 +263,16 @@ class Glib::JsonUi::ViewBuilder
|
|
263
263
|
hash :infoSpec
|
264
264
|
end
|
265
265
|
|
266
|
+
class MultipleUpload < AbstractField
|
267
|
+
hash :accepts
|
268
|
+
array :files
|
269
|
+
string :directUploadUrl
|
270
|
+
string :title
|
271
|
+
string :subtitle
|
272
|
+
string :uploadTitle
|
273
|
+
string :uploadFailedText
|
274
|
+
end
|
275
|
+
|
266
276
|
# TODO
|
267
277
|
# class MultiImage < Text
|
268
278
|
# # file_rules = { fileType: 'image/*', maxFileSize: 5000 }
|
@@ -66,6 +66,20 @@ section.rows builder: ->(template) do
|
|
66
66
|
action.dialogs_open fullscreen: 'mobile', url: json_ui_garage_url(path: 'forms/basic', mode: 'dialog')
|
67
67
|
end
|
68
68
|
|
69
|
+
if !Rails.env.test? # Prevent test failure
|
70
|
+
template.thumbnail title: 'dialogs/open (page with error)', onClick: ->(action) do
|
71
|
+
action.dialogs_open url: json_ui_garage_url(path: 'forms/non_existent', mode: 'dialog')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
template.thumbnail title: 'dialogs/open (page with dialogs/close)', onClick: ->(action) do
|
76
|
+
action.dialogs_open url: json_ui_garage_url(path: 'forms/dialogs_close', mode: 'dialog')
|
77
|
+
end
|
78
|
+
|
79
|
+
template.thumbnail title: 'dialogs/open (page with dialogs/show with updateExisting)', onClick: ->(action) do
|
80
|
+
action.dialogs_open url: json_ui_garage_url(path: 'forms/dialogs_update', mode: 'dialog')
|
81
|
+
end
|
82
|
+
|
69
83
|
template.thumbnail title: 'dialogs/oauth', onClick: ->(action) do
|
70
84
|
if respond_to?(:user_facebook_omniauth_authorize_url)
|
71
85
|
provider = {
|
@@ -5,7 +5,10 @@ markdown = '## Emphasis' + "\n" +
|
|
5
5
|
"\n" +
|
6
6
|
'~~Strikethrough~~' + "\n"
|
7
7
|
|
8
|
-
|
8
|
+
options = {
|
9
|
+
updateExisting: true
|
10
|
+
}
|
11
|
+
action.send "dialogs_#{dialog_mode}", **options, content: ->(dialog) do
|
9
12
|
dialog.body padding: glib_json_padding_body, childViews: ->(body) do
|
10
13
|
body.markdown text: markdown
|
11
14
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
json.title 'Forms'
|
2
|
+
|
3
|
+
page = json_ui_page json
|
4
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page
|
5
|
+
|
6
|
+
page.scroll childViews: ->(scroll) do
|
7
|
+
scroll.label text: 'This content will be replaced'
|
8
|
+
end
|
9
|
+
|
10
|
+
page.on load: ->(action) do
|
11
|
+
action.dialogs_close onClose: ->(subaction) do
|
12
|
+
subaction.windows_open url: json_ui_garage_url(path: 'home/blank')
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
json.title 'Forms'
|
2
|
+
|
3
|
+
page = json_ui_page json
|
4
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page
|
5
|
+
|
6
|
+
page.scroll childViews: ->(scroll) do
|
7
|
+
scroll.label text: 'This content will be replaced'
|
8
|
+
end
|
9
|
+
|
10
|
+
page.on load: ->(action) do
|
11
|
+
render 'json_ui/garage/actions/dialogs_show', json: json, action: action, dialog_mode: :show
|
12
|
+
end
|
@@ -36,5 +36,17 @@ page.form options.merge(childViews: ->(form) do
|
|
36
36
|
# form.fields_multiImage name: 'user[photos][]', width: 'matchParent', label: 'Avatar', accepts: rules, directUploadUrl: rails_direct_uploads_url,
|
37
37
|
# placeholderView: { type: 'avatar', width: 100, height: 100, url: 'data:image/jpeg;base64,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' }
|
38
38
|
|
39
|
+
form.spacer height: 16
|
40
|
+
form.fields_multipleUpload \
|
41
|
+
name: 'user[multi][]',
|
42
|
+
directUploadUrl: rails_direct_uploads_url,
|
43
|
+
title: 'Select file or drag and drop here',
|
44
|
+
subtitle: 'JPG, PNG or PDF, file size no more than 10MB',
|
45
|
+
uploadTitle: 'File added:',
|
46
|
+
uploadFailedText: '(UPLOAD FAILED)',
|
47
|
+
files: [
|
48
|
+
{ name: 'File (Example)', signed_id: ActiveStorage::Attachment.last&.signed_id }
|
49
|
+
]
|
50
|
+
form.spacer height: 16
|
39
51
|
form.fields_submit text: 'Submit'
|
40
52
|
end)
|
@@ -1,114 +1,68 @@
|
|
1
|
-
|
1
|
+
room = params[:room]
|
2
2
|
page = json_ui_page json
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
first_user = User.first
|
7
|
-
second_user = User.offset(1).first
|
8
|
-
# Implement a page that shows how ActionCable works in json_ui
|
4
|
+
random_key = SecureRandom.hex(3)
|
5
|
+
user = "randomuser##{random_key}"
|
9
6
|
|
10
|
-
|
11
|
-
# column.panels_list actionCable: socket_config, width: 'matchParent', firstSection: ->(section) do
|
12
|
-
# section.rows objects: @messages, builder: -> (row, message, index) do
|
13
|
-
# render 'conversations/message', row: row, message: message, user: current_user
|
14
|
-
# end
|
15
|
-
# end
|
7
|
+
json.title "User: #{user}"
|
16
8
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# end
|
33
|
-
|
34
|
-
page.on load: ->(action) do
|
35
|
-
action.timeouts_set interval: 1000, repeat: true, onTimeout: ->(subaction) do
|
36
|
-
subaction.cables_push channel: online_channel, event: 'online_status', payload: { status: true, user_id: first_user.id }
|
37
|
-
end
|
9
|
+
if room.present?
|
10
|
+
page.actionCable \
|
11
|
+
channels: [
|
12
|
+
{
|
13
|
+
name: 'Glib::Channel::AppearanceChannel',
|
14
|
+
options: { targetId: 'label-1', room: room }
|
15
|
+
},
|
16
|
+
{
|
17
|
+
name: 'Glib::Channel::ChatChannel',
|
18
|
+
options: { targetId: 'list-1', room: room }
|
19
|
+
}
|
20
|
+
],
|
21
|
+
onError: ->(action) do
|
22
|
+
action.labels_set targetId: 'label-1', text: "Room ##{room.upcase} (OFF)"
|
23
|
+
end
|
38
24
|
end
|
39
25
|
|
40
|
-
# 4. Example for typing status
|
41
|
-
|
42
|
-
# put on app/channels/is_typing_channel.rb
|
43
|
-
# class IsTypingChannel < Glib::Channel::IsTypingChannel
|
44
|
-
# self.channel_name = 'IsTypingChannel'
|
45
|
-
# end
|
46
|
-
|
47
26
|
page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
48
27
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
filterKey: second_user.id,
|
54
|
-
params: {
|
55
|
-
conversation: 2
|
56
|
-
}
|
57
|
-
}
|
58
|
-
left.label actionCable: online_socket_config, text: ' '
|
59
|
-
|
60
|
-
left.fields_textarea \
|
61
|
-
width: 440,
|
62
|
-
label: "Messages from #{first_user.full_name}",
|
63
|
-
onTypeStart: lambda { |action|
|
64
|
-
action.cables_push \
|
65
|
-
channel: typing_channel, event: 'typing',
|
66
|
-
payload: { status: true, user_id: first_user.id }
|
67
|
-
},
|
68
|
-
onTypeEnd: lambda { |action|
|
69
|
-
action.cables_push \
|
70
|
-
channel: typing_channel,
|
71
|
-
event: 'typing',
|
72
|
-
payload: { status: false, user_id: first_user.id }
|
73
|
-
}
|
74
|
-
left.spacer height: 10
|
28
|
+
if room.present?
|
29
|
+
scroll.panels_form url: glib_chat_url, width: 'matchParent', height: 'matchParent', method: 'POST', childViews: ->(form) do
|
30
|
+
form.fields_hidden name: 'chat[room]', value: room
|
31
|
+
form.fields_hidden name: 'chat[user]', value: user
|
75
32
|
|
76
|
-
|
77
|
-
channel: typing_channel,
|
78
|
-
filterKey: first_user.id,
|
79
|
-
params: {
|
80
|
-
conversation: 2
|
81
|
-
}
|
82
|
-
}
|
83
|
-
left.label actionCable: socket_config, text: ' '
|
84
|
-
end
|
33
|
+
form.p id: 'label-1', text: "Room ##{room.upcase}"
|
85
34
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
onTypeStart: lambda { |action|
|
92
|
-
action.cables_push \
|
93
|
-
channel: typing_channel, event: 'typing',
|
94
|
-
payload: { status: true, user_id: second_user.id }
|
95
|
-
},
|
96
|
-
onTypeEnd: lambda { |action|
|
97
|
-
action.cables_push \
|
98
|
-
channel: typing_channel,
|
99
|
-
event: 'typing',
|
100
|
-
payload: { status: false, user_id: second_user.id }
|
101
|
-
}
|
102
|
-
right.spacer height: 10
|
35
|
+
form.panels_list width: 'matchParent', height: 'matchParent', id: 'list-1', sections: [
|
36
|
+
->(section) do
|
37
|
+
section.rows builder: ->(template) do
|
38
|
+
template.thumbnail title: 'System', subtitle: 'Feel free to discuss anything here.'
|
39
|
+
end
|
103
40
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
41
|
+
section.footer childViews: ->(footer) do
|
42
|
+
form.fields_text \
|
43
|
+
name: 'chat[body]',
|
44
|
+
width: 'matchParent',
|
45
|
+
onTypeStart: ->(action) do
|
46
|
+
action.cables_push \
|
47
|
+
event: 'status',
|
48
|
+
channel: 'Glib::Channel::AppearanceChannel',
|
49
|
+
payload: { text: "#{user} is typing", room: room }
|
50
|
+
end,
|
51
|
+
onTypeEnd: ->(action) do
|
52
|
+
action.cables_push \
|
53
|
+
event: 'status',
|
54
|
+
channel: 'Glib::Channel::AppearanceChannel',
|
55
|
+
payload: { text: "Room ##{room.upcase}", room: room }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
]
|
112
60
|
end
|
61
|
+
|
62
|
+
else
|
63
|
+
scroll.button text: 'Goto room', onClick: ->(action) { action.windows_open url: json_ui_garage_url(path: 'notifications/action_cable', room: random_key) }
|
64
|
+
scroll.spacer height: 8
|
65
|
+
scroll.label text: 'Or you can ask other dev for room (by copying the url)'
|
113
66
|
end
|
67
|
+
|
114
68
|
end
|
@@ -9,8 +9,6 @@
|
|
9
9
|
<%= csrf_meta_tags %>
|
10
10
|
|
11
11
|
<%= vite_javascript_tag 'vue_renderer', defer: true %>
|
12
|
-
<%#= javascript_include_tag 'vue_renderer_extras', defer: true %>
|
13
|
-
|
14
12
|
<%= vite_stylesheet_tag 'vue_renderer' %>
|
15
13
|
<%# TODO: Remove this, for dev only %>
|
16
14
|
<%# <script src="https://cdn.tailwindcss.com"></script> %>
|
data/config/routes.rb
CHANGED
@@ -7,9 +7,8 @@ module Glib
|
|
7
7
|
|
8
8
|
VALID_RESPONSE_CODES = [
|
9
9
|
(200..299).to_a,
|
10
|
-
##
|
11
|
-
|
12
|
-
# 403, ## FORBIDDEN Should be used for logged-in but not allowed to access
|
10
|
+
401, ## UNAUTHORIZED Should be used for not-logged-in
|
11
|
+
403, ## FORBIDDEN Should be used for logged-in but not allowed to access
|
13
12
|
].flatten
|
14
13
|
|
15
14
|
def initialize(context, user, router)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glib-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
@@ -72,6 +72,8 @@ executables: []
|
|
72
72
|
extensions: []
|
73
73
|
extra_rdoc_files: []
|
74
74
|
files:
|
75
|
+
- app/channels/glib/channel/appearance_channel.rb
|
76
|
+
- app/channels/glib/channel/chat_channel.rb
|
75
77
|
- app/channels/glib/channel/is_typing_channel.rb
|
76
78
|
- app/channels/glib/channel/online_channel.rb
|
77
79
|
- app/controllers/concerns/glib/analytics/funnel.rb
|
@@ -95,6 +97,7 @@ files:
|
|
95
97
|
- app/helpers/glib/json_ui/action_builder/commands.rb
|
96
98
|
- app/helpers/glib/json_ui/action_builder/components.rb
|
97
99
|
- app/helpers/glib/json_ui/action_builder/dialogs.rb
|
100
|
+
- app/helpers/glib/json_ui/action_builder/fields.rb
|
98
101
|
- app/helpers/glib/json_ui/action_builder/http.rb
|
99
102
|
- app/helpers/glib/json_ui/action_builder/iap.rb
|
100
103
|
- app/helpers/glib/json_ui/action_builder/panels.rb
|
@@ -148,6 +151,7 @@ files:
|
|
148
151
|
- app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder
|
149
152
|
- app/views/json_ui/garage/actions/index.json.jbuilder
|
150
153
|
- app/views/json_ui/garage/actions/partial_update.json.jbuilder
|
154
|
+
- app/views/json_ui/garage/empty.json.jbuilder
|
151
155
|
- app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder
|
152
156
|
- app/views/json_ui/garage/forms/_conditional_banner.json.jbuilder
|
153
157
|
- app/views/json_ui/garage/forms/_partial_update_execute.json.jbuilder
|
@@ -156,6 +160,8 @@ files:
|
|
156
160
|
- app/views/json_ui/garage/forms/basic_post.json.jbuilder
|
157
161
|
- app/views/json_ui/garage/forms/checkboxes.json.jbuilder
|
158
162
|
- app/views/json_ui/garage/forms/conditional_value.json.jbuilder
|
163
|
+
- app/views/json_ui/garage/forms/dialogs_close.json.jbuilder
|
164
|
+
- app/views/json_ui/garage/forms/dialogs_update.json.jbuilder
|
159
165
|
- app/views/json_ui/garage/forms/dirty_prompt.json.jbuilder
|
160
166
|
- app/views/json_ui/garage/forms/dynamic_group.json.jbuilder
|
161
167
|
- app/views/json_ui/garage/forms/dynamic_select.json.jbuilder
|
@@ -269,6 +275,7 @@ files:
|
|
269
275
|
- app/views/json_ui/garage/views/shareButton.json.jbuilder
|
270
276
|
- app/views/json_ui/garage/views/steppers.json.jbuilder
|
271
277
|
- app/views/json_ui/garage/views/texts.json.jbuilder
|
278
|
+
- app/views/layouts/json_ui/no_custom.html.erb
|
272
279
|
- app/views/layouts/json_ui/renderer.html.erb
|
273
280
|
- config/routes.rb
|
274
281
|
- lib/generators/glib/install_generator.rb
|