Merge: Added contributing guidelines and link from 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 private var list = new ListLayout(parent=self)
90 private var lbl_feedback = new Label(parent=list, text="Welcome")
91
92 private var layout_login = new VerticalLayout(parent=list)
93
94 # ---
95 # First the login options
96
97 # Name
98 private var name_line = new HorizontalLayout(parent=layout_login)
99 private var lbl_name = new Label(parent=name_line, text="Username".t)
100 private var txt_name = new TextInput(parent=name_line, text=app.user)
101
102 # Password
103 private var pass_line = new HorizontalLayout(parent=layout_login)
104 private var lbl_pass = new Label(parent=pass_line, text="Password".t)
105 private var txt_pass = new TextInput(parent=pass_line, is_password=true)
106 private var lbl_pass_desc = new Label(parent=layout_login, size = 0.5,
107 text="Passwords must be composed of at least 6 characters.".t)
108
109 private var but_login = new Button(parent=layout_login, text="Login".t)
110
111 # ---
112 # Then, the signup options
113
114 private var layout_register = new VerticalLayout(parent=list)
115
116 private var lbl_signup_desc = new Label(parent=layout_register, size = 0.5,
117 text="Fill the following fields to sign up.".t)
118
119 # Repeat password
120 private var pass_line2 = new HorizontalLayout(parent=layout_register)
121 private var lbl_pass2 = new Label(parent=pass_line2, text="Repeat password".t)
122 private var txt_pass2 = new TextInput(parent=pass_line2, is_password=true)
123
124 # Email
125 private var email_line = new HorizontalLayout(parent=layout_register)
126 private var lbl_email = new Label(parent=email_line, text="Email".t)
127 private var txt_email = new TextInput(parent=email_line)
128
129 private var but_signup = new Button(parent=layout_register, text="Signup".t)
130
131 init
132 do
133 for c in [but_login, but_signup] do
134 c.observers.add self
135 end
136 end
137
138 redef fun on_event(event)
139 do
140 if debug then print "BenitluxWindow::on_event {event}"
141
142 if event isa ButtonPressEvent then
143 var sender = event.sender
144 if sender == but_login or sender == but_signup then
145
146 var name = txt_name.text
147 if name == null or not name.name_is_ok then
148 feedback "Invalid username.".t
149 return
150 end
151
152 var pass = txt_pass.text
153 if pass == null or not pass.pass_is_ok then
154 feedback "Invalid password.".t
155 return
156 end
157
158 if sender == but_login then
159 feedback "Logging in...".t
160 (new LoginOrSignupAction(self, "rest/login?name={name}&pass={pass.pass_hash}")).start
161 else if sender == but_signup then
162 if pass != txt_pass2.text then
163 feedback "Passwords do not match.".t
164 return
165 end
166
167 var email = txt_email.text
168 if email == null or email.is_empty then
169 feedback "Invalid email".t
170 return
171 end
172
173 feedback "Signing up...".t
174 (new LoginOrSignupAction(self, "rest/signup?name={name}&pass={pass.pass_hash}&email={email}")).start
175 end
176 end
177 end
178
179 super
180 end
181
182 # Show lasting feedback to the user in a label
183 fun feedback(text: String) do lbl_feedback.text = text
184 end
185
186 # ---
187 # Async RESTful actions
188
189 # Async request for login in or signing up
190 class LoginOrSignupAction
191 super WindowHttpRequest
192
193 redef type W: SignupWindow
194
195 init do affected_views.add_all([window.but_login, window.but_signup])
196
197 redef fun on_load(res)
198 do
199 if intercept_error(res) then return
200
201 if not res isa LoginResult then
202 on_fail new Error("Server sent unexpected data {res or else "null"}")
203 return
204 end
205
206 app.token = res.token
207 app.user = res.user.name
208
209 app.on_log_in
210 end
211
212 redef fun feedback(text) do window.feedback text
213 end