Skip to content

Commit 691d9c7

Browse files
authored
Merge pull request #359 from snap-cloud/frontend-bootstrap
WIP: Migrate frontend styles to bootstrap
2 parents e28df80 + caf9cec commit 691d9c7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1550
-318
lines changed

locales/ca.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ local locale = {
7878
welcome_logged_in = "Hola, @1!", -- @1 becomes the current user username
7979
snap_description = "Snap@1 és un llenguatge àmpliament acollidor tant per a nens i nenes com per a adults, així com una plataforma per a un estudi rigorós de les ciències de la computació.",
8080
-- Buttons
81-
run_now = "Obre Snap@1 ara",
81+
run_now = "Obre @1 ara",
8282
-- examples and manual already translated in Footer
8383
-- Curated Collections
8484
featured = "Projectes destacats",

locales/en.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ local locale = {
7979
welcome_logged_in = "Welcome, @1!", -- @1 becomes the current user username
8080
snap_description = "Snap@1 is a broadly inviting programming language for kids and adults that's also a platform for serious study of computer science.",
8181
-- Buttons
82-
run_now = "Run Snap@1 Now",
82+
run_now = "Run @1 Now",
8383
-- examples and manual already translated in Footer
8484
-- Curated Collections
8585
featured = "Featured Projects",

locales/es.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ local locale = {
8080
welcome_logged_in = "¡Hola, @1!", -- @1 becomes the current user username
8181
snap_description = "Snap@1 es un lenguaje ámpliamente acogedor tanto para niños y niñas como para adultos, así como también una plataforma para un estudio riguroso de las ciencias de la computación.",
8282
-- Buttons
83-
run_now = "Abre Snap@1 ahora",
83+
run_now = "Abre @1 ahora",
8484
-- examples and manual already translated in Footer
8585
-- Curated Collections
8686
featured = "Proyectos destacados",

site.lua

+60-38
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ local Projects = package.loaded.Projects
3333
local Remixes = package.loaded.Remixes
3434
local Collections = package.loaded.Collections
3535
local FlaggedProjects = package.loaded.FlaggedProjects
36-
local db = package.loaded.db
3736
local assert_exists = require('validation').assert_exists
3837

3938
require 'controllers.user'
@@ -45,30 +44,52 @@ require 'dialogs'
4544
app:enable('etlua')
4645
app.layout = require 'views.layout'
4746

48-
local views = {
49-
-- Static pages
50-
'about', 'bjc', 'coc', 'contact', 'credits', 'dmca', 'extensions',
47+
local static_pages = {
48+
'about', 'bjc', 'blog', 'coc', 'contact', 'credits', 'dmca', 'extensions',
5149
'materials', 'mirrors', 'offline', 'partners', 'privacy', 'research',
52-
'snapinator', 'snapp', 'source', 'tos',
50+
'snapinator', 'snapp', 'source', 'tos'
51+
}
5352

53+
local views = {
5454
-- Simple pages
55-
'blog', 'change_email', 'change_password', 'delete_user', 'forgot_password',
56-
'forgot_username', 'sign_up', 'login',
55+
'change_email', 'change_password', 'delete_user', 'forgot_password',
56+
'forgot_username', 'sign_up', 'login'
5757
}
5858

59+
-- Temporary during a front-end rewrite.
60+
-- This allows testing anypage with adding ?bootstrap=true to the URL
61+
app:before_filter(function (self)
62+
if self.current_user and self.current_user:isadmin() then
63+
if self.params['bootstrap'] == 'true' then
64+
app.layout = 'layout_bs'
65+
end
66+
end
67+
end)
68+
5969
app:get('index', '/', capture_errors(cached(function (self)
6070
self.snapcloud_id = Users:find({ username = 'snapcloud' }).id
61-
return { render = 'index' }
71+
-- return { render = 'index' }
72+
return { render = 'index_bs', layout = 'layout_bs' }
6273
end)))
6374

6475
-- Backwards compatibility.
6576
app:get('/index', function ()
6677
return { redirect_to = '/' }
6778
end)
6879

80+
for _, page in pairs(static_pages) do
81+
app:get('/' .. page, capture_errors(cached(function (self)
82+
return { render = 'static/' .. page, layout = 'layout_bs' }
83+
end)))
84+
end
85+
6986
for _, view in pairs(views) do
7087
app:get('/' .. view, capture_errors(cached(function (self)
71-
return { render = view }
88+
if self.params['bootstrap'] then
89+
return { render = view .. '_bs', layout = 'layout_bs'}
90+
else
91+
return { render = view }
92+
end
7293
end)))
7394
end
7495

@@ -84,30 +105,30 @@ end))
84105

85106
app:get('/explore', capture_errors(cached(function (self)
86107
self.items = ProjectController.fetch(self)
87-
return { render = 'explore' }
108+
return { render = 'explore', layout = 'layout_bs' }
88109
end)))
89110

90111
app:get('/collections', capture_errors(cached(function (self)
91112
self.items = CollectionController.fetch(self)
92-
return { render = 'collections' }
113+
return { render = 'collections', layout = 'layout_bs' }
93114
end)))
94115

95116
app:get('/all_totms', capture_errors(cached(function (self)
96117
self.items = CollectionController.totms(self)
97-
return { render = 'all_totms' }
118+
return { render = 'all_totms', layout = 'layout_bs' }
98119
end)))
99120

100121
app:get('/users', capture_errors(cached(function (self)
101122
self.items_per_page = 51
102123
self.items = UserController.fetch(self)
103124
if not self.params.search_term then self.params.search_term = '' end
104-
return { render = 'users' }
125+
return { render = 'users', layout = 'layout_bs' }
105126
end)))
106127

107128
app:get('/my_projects', capture_errors(function (self)
108129
if self.current_user then
109130
self.items = ProjectController.my_projects(self)
110-
return { render = 'my_projects' }
131+
return { render = 'my_projects', layout = 'layout_bs' }
111132
else
112133
return { redirect_to = self:build_url('/') }
113134
end
@@ -116,7 +137,7 @@ end))
116137
app:get('/my_collections', capture_errors(function (self)
117138
if self.current_user then
118139
self.items = CollectionController.my_collections(self)
119-
return { render = 'my_collections' }
140+
return { render = 'my_collections', layout = 'layout_bs' }
120141
else
121142
return { redirect_to = self:build_url('/') }
122143
end
@@ -153,20 +174,20 @@ app:get('/user', capture_errors(function (self)
153174
assert_user_exists(self)
154175
self.username = self.queried_user.username
155176
self.user_id = self.queried_user.id
156-
return { render = 'user' }
177+
return { render = 'user', layout = 'layout_bs' }
157178
end))
158179

159180
app:get('/user_collections/:username', capture_errors(cached(function (self)
160181
assert_user_exists(self)
161182
self.params.user_id = self.queried_user.id
162183
self.items = CollectionController.user_collections(self)
163-
return { render = 'collections' }
184+
return { render = 'collections', layout = 'layout_bs' }
164185
end)))
165186

166187
app:get('/user_projects/:username', capture_errors(cached(function (self)
167188
assert_user_exists(self)
168189
self.items = ProjectController.user_projects(self)
169-
return { render = 'explore' }
190+
return { render = 'explore', layout = 'layout_bs' }
170191
end)))
171192

172193
-- Display an embedded collection view.
@@ -187,7 +208,7 @@ end)))
187208
app:get('/followed', capture_errors(cached(function (self)
188209
if self.current_user then
189210
self.items = ProjectController.followed_projects(self)
190-
return { render = 'followed' }
211+
return { render = 'followed', layout = 'layout_bs' }
191212
else
192213
return { redirect_to = self:build_url('/') }
193214
end
@@ -196,7 +217,7 @@ end)))
196217
app:get('/followed_users', capture_errors(cached(function (self)
197218
if self.current_user then
198219
self.items = UserController.followed_users(self)
199-
return { render = 'followed_users' }
220+
return { render = 'followed_users', layout = 'layout_bs' }
200221
else
201222
return { redirect_to = self:build_url('/') }
202223
end
@@ -205,7 +226,7 @@ end)))
205226
app:get('/my_followers', capture_errors(cached(function (self)
206227
if self.current_user then
207228
self.items = UserController.follower_users(self)
208-
return { render = 'my_followers' }
229+
return { render = 'my_followers', layout = 'layout_bs' }
209230
else
210231
return { redirect_to = self:build_url('/') }
211232
end
@@ -256,23 +277,23 @@ app:match('project', '/project', capture_errors(function (self)
256277
return { render = 'project' }
257278
end))
258279

280+
-- TODO: Should be able to consolidate these pages.
259281
app:get('/examples', capture_errors(cached(function (self)
260282
self.snapcloud_id = Users:find({ username = 'snapcloud' }).id
261-
return { render = 'examples' }
283+
return { render = 'examples', layout = 'layout_bs' }
262284
end)))
263285

264286
app:get('/events', capture_errors(cached(function (self)
265287
self.snapcloud_id = Users:find({ username = 'snapcloud' }).id
266-
return { render = 'events' }
288+
return { render = 'events', layout = 'layout_bs' }
267289
end)))
268290

269291
app:get('/search', capture_errors(function (self)
270292
self.reviewer_controls =
271293
self.current_user and self.current_user:has_min_role('reviewer')
272-
return { render = 'search' }
294+
return { render = 'search', layout = 'layout_bs' }
273295
end))
274296

275-
-- Administration and data management pages
276297

277298
app:get('/profile', capture_errors(function (self)
278299
if self.current_user then
@@ -283,10 +304,12 @@ app:get('/profile', capture_errors(function (self)
283304
end
284305
end))
285306

307+
-- Administration and data management pages
308+
286309
app:get('/admin', capture_errors(function (self)
287310
if self.current_user then
288311
assert_min_role(self, 'reviewer')
289-
return { render = 'admin' }
312+
return { render = 'admin/index', layout = 'layout_bs' }
290313
else
291314
return { redirect_to = self:build_url('/') }
292315
end
@@ -296,7 +319,7 @@ app:get('/flags', capture_errors(function (self)
296319
if self.current_user then
297320
assert_min_role(self, 'reviewer')
298321
items = ProjectController.flagged_projects(self)
299-
return { render = 'flags' }
322+
return { render = 'admin/flags' }
300323
else
301324
return { redirect_to = self:build_url('/') }
302325
end
@@ -307,7 +330,7 @@ app:get('/user_admin', capture_errors(function (self)
307330
if self.current_user then
308331
assert_min_role(self, 'moderator')
309332
self.items = UserController.fetch(self)
310-
return { render = 'user_admin' }
333+
return { render = 'admin/user_admin', layout = 'layout_bs' }
311334
else
312335
return { redirect_to = self:build_url('/') }
313336
end
@@ -318,17 +341,17 @@ app:get('/zombie_admin', capture_errors(function (self)
318341
if self.current_user then
319342
assert_min_role(self, 'moderator')
320343
self.items = UserController.zombies(self)
321-
return { render = 'zombie_admin' }
344+
return { render = 'admin/zombie_admin' }
322345
else
323346
return { redirect_to = self:build_url('/') }
324347
end
325348
end))
326349

327-
app:match('/totm', respond_to({
350+
app:match('admin/totm', '/totm', respond_to({
328351
GET = capture_errors(function (self)
329352
if self.current_user then
330353
assert_min_role(self, 'moderator')
331-
return { render = 'totm' }
354+
return { render = true, layout = 'layout_bs' }
332355
else
333356
return { redirect_to = self:build_url('/') }
334357
end
@@ -339,7 +362,7 @@ app:match('/totm', respond_to({
339362
if file then
340363
local disk = package.loaded.disk
341364
if disk:save_totm_banner(file) then
342-
return { render = 'totm' }
365+
return { render = true, layout = 'layout_bs' }
343366
end
344367
end
345368
return errorResponse(self)
@@ -348,13 +371,13 @@ app:match('/totm', respond_to({
348371

349372
app:get('/carousel_admin', capture_errors(function (self)
350373
assert_min_role(self, 'moderator')
351-
return { render = 'carousel_admin' }
374+
return { render = 'admin/carousel_admin' }
352375
end))
353376

354377
app:get('/ip_admin', capture_errors(function (self)
355378
assert_min_role(self, 'admin')
356379
self.ips = SiteController.banned_ips(self)
357-
return { render = 'ip_admin' }
380+
return { render = 'admin/ip_admin' }
358381
end))
359382

360383
-- Teachers
@@ -364,15 +387,15 @@ app:get('/teacher', capture_errors(function (self)
364387
if (not self.current_user.is_teacher) then
365388
assert_admin(self)
366389
end
367-
return { render = 'teacher' }
390+
return { render = 'teacher/index', layout = 'layout_bs' }
368391
end))
369392

370393
app:get('/bulk', capture_errors(function (self)
371394
assert_exists(self.current_user)
372395
if (not self.current_user.is_teacher) then
373396
assert_admin(self)
374397
end
375-
return { render = 'bulk' }
398+
return { render = 'teacher/bulk', layout = 'layout_bs' }
376399
end))
377400

378401
app:get('/learners', capture_errors(function (self)
@@ -384,14 +407,13 @@ app:get('/learners', capture_errors(function (self)
384407
self.items_per_page = 150
385408
if self.current_user and self.current_user.is_teacher then
386409
self.items = UserController.learners(self)
387-
return { render = 'learners' }
410+
return { render = 'teacher/learners', layout = 'layout_bs' }
388411
else
389412
return { redirect_to = self:build_url('index') }
390413
end
391414
end))
392415

393416
-- Tools
394-
395417
--[[
396418
app:get('/localize', capture_errors(function (self)
397419
return { render = 'localize' }

static/img/lowfloor.png

-511 Bytes
Loading

static/js/base.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
var snapURL = location.origin + '/snap/snap.html',
22
snapDevURL = location.origin + '/snapsource/dev/snap.html',
3-
baseURL = location.protocol + '//' + location.host,
43
nop = function () {},
54
localizer = new Localizer(),
65
buttonDefaults =
@@ -10,7 +9,7 @@ function encodeParams (params) {
109
if (params) {
1110
return '?' +
1211
Object.keys(params).map(
13-
paramName =>
12+
paramName =>
1413
encodeURIComponent(paramName) + '=' +
1514
encodeURIComponent(JSON.stringify(params[paramName]))
1615
).join('&');
@@ -95,6 +94,24 @@ function flash (element, callback, warning) {
9594
}, 500);
9695
};
9796

97+
function setupCarouselPageIndicator (id) {
98+
function setCarouselText(carousel, current, total) {
99+
let textContainer = carousel.querySelector('.js-textStatus');
100+
textContainer.querySelector('.page-link').innerHTML = `${current} / ${total}`;
101+
textContainer.querySelector('.visually-hidden').innerHTML = `${current} of ${total}`;
102+
}
103+
104+
let carousel = document.getElementById(`${id}_container`);
105+
let totalItems = carousel.querySelectorAll('.carousel-item').length;
106+
let currentIndex = Array.prototype.indexOf.call(carousel.querySelectorAll('.carousel-item'), carousel.querySelector('div.active')) + 1;
107+
setCarouselText(carousel, currentIndex, totalItems);
108+
109+
carousel.addEventListener('slid.bs.carousel', function() {
110+
currentIndex = Array.prototype.indexOf.call(carousel.querySelectorAll('.carousel-item'), carousel.querySelector('div.active')) + 1;
111+
setCarouselText(carousel, currentIndex, totalItems);
112+
});
113+
};
114+
98115
// JS additions
99116

100117
Array.prototype.sortBy = function (parameter, reverse) {

0 commit comments

Comments
 (0)