nit: Added link to `CONTRIBUTING.md` from the README
[nit.git] / contrib / benitlux / src / client / views / user_views.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # User preference window and other user-related view
16 module user_views
17
18 import base
19
20 redef class Label
21 # Update the content of `lbl_welcome`
22 fun set_user_name
23 do
24 var name = app.user
25 self.text = if name != null then
26 "Logged in as %0".t.format(name)
27 else "Not logged in".t
28 end
29
30 # Set `text` to welcome an authentified user or invite to authentify
31 fun set_welcome
32 do
33 var name = app.user
34 self.text = if name != null then
35 "Welcome %0".t.format(name)
36 else ""
37 end
38 end
39
40 # User preference window
41 class UserWindow
42 super Window
43
44 # Main window layout
45 var layout = new ListLayout(parent=self)
46
47 private var layout_user_options = new VerticalLayout(parent=layout)
48
49 private var lbl_user_options_title = new Label(parent=layout_user_options,
50 text="Account options".t)
51
52 private var lbl_welcome = new Label(parent=layout_user_options)
53 private var but_logout = new Button(parent=layout_user_options, text="Logout".t)
54
55 # Refesh displayed text
56 fun refresh
57 do
58 lbl_user_options_title.size = 1.5
59 lbl_welcome.set_user_name
60 but_logout.enabled = app.user != null
61 end
62
63 init
64 do
65 but_logout.observers.add self
66 refresh
67 end
68
69 redef fun on_event(event)
70 do
71 if event isa ButtonPressEvent then
72 var sender = event.sender
73 if sender == but_logout then
74 app.user = null
75 app.token = "none"
76 app.on_log_in
77 refresh
78 end
79 end
80
81 super
82 end
83 end
84
85 # Window for signing up a new user or logging in
86 class SignupWindow
87 super Window
88
89 # Main window layout
90 var layout = new ListLayout(parent=self)
91
92 private var lbl_welcome = new Label(parent=layout, text="Welcome")
93
94 # Name
95 private var name_line = new HorizontalLayout(parent=layout)
96 private var lbl_name = new Label(parent=name_line, text="Username".t)
97 private var txt_name = new TextInput(parent=name_line, text=app.user)
98
99 # Pass
100 private var pass_line = new HorizontalLayout(parent=layout)
101 private var lbl_pass = new Label(parent=pass_line, text="Password".t)
102 private var txt_pass = new TextInput(parent=pass_line, is_password=true)
103 private var lbl_pass_desc = new Label(parent=layout,
104 text="Passwords must be composed of at least 6 characters.".t)
105
106 private var but_login = new Button(parent=layout, text="Login".t)
107
108 # Email
109 private var email_line = new HorizontalLayout(parent=layout)
110 private var lbl_email = new Label(parent=email_line, text="Email".t)
111 private var txt_email = new TextInput(parent=email_line)
112
113 private var but_signup = new Button(parent=layout, text="Signup".t)
114
115 private var lbl_feedback = new Label(parent=layout, text="")
116
117 init
118 do
119 lbl_pass_desc.size = 0.5
120
121 for c in [but_login, but_signup] do
122 c.observers.add self
123 end
124 end
125
126 redef fun on_event(event)
127 do
128 if debug then print "BenitluxWindow::on_event {event}"
129
130 if event isa ButtonPressEvent then
131 var sender = event.sender
132 if sender == but_login or sender == but_signup then
133
134 var name = txt_name.text
135 if name == null or not name.name_is_ok then
136 feedback "Invalid name".t
137 return
138 end
139
140 var pass = txt_pass.text
141 if pass == null or not pass.pass_is_ok then
142 feedback "Invalid password".t
143 return
144 end
145
146 if sender == but_login then
147 (new LoginOrSignupAction(self, "rest/login?name={name}&pass={pass.pass_hash}")).start
148 else if sender == but_signup then
149 var email = txt_email.text
150 if email == null or email.is_empty then
151 feedback "Invalid email".t
152 return
153 end
154
155 (new LoginOrSignupAction(self, "rest/signup?name={name}&pass={pass.pass_hash}&email={email}")).start
156 end
157 end
158 end
159
160 super
161 end
162
163 # Show lasting feedback to the user in a label
164 fun feedback(text: String) do lbl_feedback.text = text
165 end
166
167 # ---
168 # Async RESTful actions
169
170 # Async request for login in or signing up
171 class LoginOrSignupAction
172 super WindowHttpRequest
173
174 redef type W: SignupWindow
175
176 init do affected_views.add_all([window.but_login, window.but_signup])
177
178 redef fun on_load(res)
179 do
180 if intercept_error(res) then return
181
182 if not res isa LoginResult then
183 on_fail new Error("Server sent unexpected data {res or else "null"}")
184 return
185 end
186
187 app.token = res.token
188 app.user = res.user.name
189
190 app.on_log_in
191 end
192 end
193
194 # Async request for signing up
195 class SignupAction
196 super WindowHttpRequest
197
198 redef type W: SignupWindow
199
200 init do affected_views.add_all([window.but_signup])
201
202 redef fun on_load(res)
203 do
204 if intercept_error(res) then return
205
206 if not res isa LoginResult then
207 on_fail new Error("Server sent unexpected data {res or else "null"}")
208 return
209 end
210
211 app.token = res.token
212 app.user = res.user.name
213 app.on_log_in
214 end
215 end