b523013d4104130c10e5e8e3809e754aba5ebdd2
[nit.git] / contrib / benitlux / src / client / views / social_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 # Window to list beers and other beer-related views
16 module social_views
17
18 import base
19
20 # Social pane with networking features
21 class SocialWindow
22 super Window
23
24 private var layout = new VerticalLayout(parent=self)
25
26 private var list_search = new ListLayout(parent=layout)
27
28 private var layout_header = new VerticalLayout(parent=list_search)
29 private var layout_search = new HorizontalLayout(parent=layout_header)
30 private var txt_query = new TextInput(parent=layout_search)
31 private var but_search = new Button(parent=layout_search, text="Search".t)
32
33 private var layout_list = new HorizontalLayout(parent=layout_header)
34 private var but_followed = new Button(parent=layout_list, text="List followed".t)
35 private var but_followers = new Button(parent=layout_list, text="List followers".t)
36
37 init
38 do
39 for c in [but_search, but_followed, but_followers] do
40 c.observers.add self
41 end
42
43 # Load friends and suggestions
44 (new ListUsersAction(self, "rest/friends?token={app.token}&n=16")).start
45 end
46
47 redef fun on_event(event)
48 do
49 if debug then print "BenitluxWindow::on_event {event}"
50
51 if event isa ButtonPressEvent then
52 var sender = event.sender
53 if sender == but_search then
54 search
55 else if sender == but_followed then
56 var cmd = "rest/followed?token={app.token}"
57 (new ListUsersAction(self, cmd)).start
58 else if sender == but_followers then
59 var cmd = "rest/followers?token={app.token}"
60 (new ListUsersAction(self, cmd)).start
61 end
62 end
63
64 super
65 end
66
67 # Execute search with `txt_query.text`
68 fun search
69 do
70 var query = txt_query.text
71 if query == null or query.is_empty then return
72
73 var res = "rest/search?token={app.token}&query={query}&offset=0"
74 (new ListUsersAction(self, res)).start
75 end
76
77 # Fill `list_search` with views for each of `users`
78 fun list_users(users: Array[UserAndFollowing])
79 do
80 for uaf in users do
81 var view = new PeopleView(uaf, false, parent=list_search)
82 end
83 end
84 end
85
86 # View to describe, and follow a person
87 class PeopleView
88 super VerticalLayout
89 super ItemView
90
91 autoinit user_and_following, home_window_mode, parent
92
93 # Description of the user
94 var user_and_following: UserAndFollowing
95
96 # Toggle tweaks for the home window where the is no "unfollow" buttons
97 var home_window_mode: Bool
98
99 init
100 do
101 var user = user_and_following.user
102
103 var layout_top_line = new HorizontalLayout(parent=self)
104 var lbl_name = new Label(parent=layout_top_line, text=user.name)
105
106 if app.user != null then
107
108 # Show unfollow button if not on the home screen
109 if not home_window_mode or not user_and_following.following then
110 var but = new FollowButton(user.id, user_and_following.following, user_and_following.followed, parent=layout_top_line)
111 but.observers.add self
112 end
113 end
114
115 var favs = if not user_and_following.favs.is_empty then
116 "Favorites: %0".t.format(user_and_following.favs)
117 else "No favorites yet".t
118 var lbl_desc = new Label(parent=self, text=favs, size=0.5)
119 end
120 end
121
122 # Button to follow or unfollow a user
123 class FollowButton
124 super Button
125
126 autoinit followed_id, following, followed_by, parent, enabled, text
127
128 # Id of the user to be followd/unfollow
129 var followed_id: Int
130
131 # Does the local user already follows `followed_id`
132 var following: Bool
133
134 # Does `followed_id` already follows the local user
135 var followed_by: Bool
136
137 # Update the visible text according to `following`
138 fun update_text do text = if following then "Unfollow".t else "Follow".t
139
140 init do update_text
141
142 redef fun on_event(event)
143 do
144 assert event isa ButtonPressEvent
145 var cmd = "rest/follow?token={app.token}&user_to={followed_id}&follow={not following}"
146 enabled = false
147 text = "Updating...".t
148 (new FollowAction(app.window, cmd, self)).start
149 end
150 end
151
152 # Async request to receive and display a list of users
153 #
154 # This is used by many features of the social window:
155 # search, list followed and list followers.
156 class ListUsersAction
157 super WindowHttpRequest
158
159 redef type W: SocialWindow
160
161 init do affected_views.add_all([window.but_search, window.but_followed, window.but_followers])
162
163 redef fun on_load(users, status)
164 do
165 window.layout.remove window.list_search
166 window.list_search = new ListLayout(parent=window.layout)
167 window.layout_header.parent = window.list_search
168
169 if intercept_error(users) then return
170
171 if users isa Array[UserAndFollowing] then window.list_users users
172 end
173 end
174
175 # Async request to follow or unfollow a user
176 class FollowAction
177 super WindowHttpRequest
178
179 private var button: FollowButton
180 init do affected_views.add(button)
181
182 redef fun on_load(res, status)
183 do
184 if intercept_error(res) then return
185 end
186
187 redef fun after
188 do
189 button.following = not button.following
190 button.update_text
191 button.enabled = true
192
193 super
194 end
195
196 redef fun before
197 do
198 button.enabled = false
199 super
200 end
201 end