Skip to content

Commit f6da510

Browse files
committed
move web stuffs into web directory
1 parent 44de3c5 commit f6da510

File tree

11 files changed

+692
-0
lines changed

11 files changed

+692
-0
lines changed

.editorconfig

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# EditorConfig helps developers define and maintain consistent
2+
# coding styles between different editors and IDEs
3+
# editorconfig.org
4+
5+
root = true
6+
7+
8+
[*]
9+
10+
# change these settings to your own preference
11+
indent_style = space
12+
indent_size = 2
13+
14+
# we recommend you to keep these unchanged
15+
end_of_line = lf
16+
charset = utf-8
17+
trim_trailing_whitespace = true
18+
insert_final_newline = true
19+
20+
[*.md]
21+
trim_trailing_whitespace = false
22+
23+
[{package,bower}.json]
24+
indent_style = space
25+
indent_size = 2
26+
27+
[*.hs]
28+
indent_style = space
29+
indent_size = 4

web/.bowerrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"directory": "bower_components"
3+
}

web/.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules
2+
dist
3+
.tmp
4+
.sass-cache
5+
bower_components
6+
test/bower_components

web/.jshintrc

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"browser": true,
3+
"node": true,
4+
"esnext": true,
5+
"bitwise": true,
6+
"camelcase": true,
7+
"curly": true,
8+
"eqeqeq": true,
9+
"immed": true,
10+
"indent": 2,
11+
"latedef": true,
12+
"newcap": true,
13+
"noarg": true,
14+
"quotmark": "single",
15+
"undef": true,
16+
"unused": true,
17+
"strict": true,
18+
"jquery": true
19+
}

web/app/favicon.ico

4.19 KB
Binary file not shown.

web/app/index.html

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!doctype html>
2+
<html lang="">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="description" content="">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<base href="/">
8+
<title>expec</title>
9+
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
10+
11+
<!-- build:css styles/vendor.css -->
12+
<!-- bower:css -->
13+
<!-- endbower -->
14+
<!-- endbuild -->
15+
16+
<!-- build:css styles/main.css -->
17+
<link rel="stylesheet" href="styles/main.css">
18+
<!-- endbuild -->
19+
20+
</head>
21+
<body>
22+
<!--[if lt IE 10]>
23+
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
24+
<![endif]-->
25+
26+
<div id="container"></div>
27+
28+
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
29+
<script>
30+
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
31+
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
32+
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
33+
e.src='//www.google-analytics.com/analytics.js';
34+
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
35+
ga('create','UA-XXXXX-X');ga('send','pageview');
36+
</script>
37+
38+
<!-- build:js scripts/vendor.js -->
39+
<!-- bower:js -->
40+
<script src="/bower_components/director/build/director.js"></script>
41+
<!-- endbower -->
42+
<!-- endbuild -->
43+
44+
<!-- build:js scripts/main.js -->
45+
<script src="scripts/main.js"></script>
46+
<!-- endbuild -->
47+
</body>
48+
</html>

web/app/scripts/main.js

+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/* jshint devel:true */
2+
var homepageHandler = function() {
3+
var request = new XMLHttpRequest();
4+
request.open('GET', '/api/talks', true);
5+
6+
request.onload = function() {
7+
if (request.status >= 200 && request.status < 400) {
8+
var data = JSON.parse(request.responseText);
9+
data.slice(0, 5).forEach(addTalk);
10+
}
11+
};
12+
request.send();
13+
14+
var $talks = document.getElementById('talks');
15+
function addTalk(talk) {
16+
var template = '<a href="/talks/{{slug}}"><img src="{{src}}"><p>{{title}}</p></a>';
17+
var div = document.createElement('div');
18+
div.innerHTML = template.replace('{{slug}}', talk.slug)
19+
.replace('{{src}}', talk.image)
20+
.replace('{{title}}', talk.name);
21+
div.className = 'tile';
22+
$talks.appendChild(div);
23+
}
24+
};
25+
26+
var talkPageHandler = function(slug) {
27+
var request = new XMLHttpRequest();
28+
var url = '/api/talks/' + slug + '?languages=true';
29+
request.open('GET', url, true);
30+
31+
request.onload = function() {
32+
if (request.status >= 200 && request.status < 400) {
33+
var data = JSON.parse(request.responseText);
34+
data.languages.forEach(addLanguage);
35+
addVideoDownloads(data.talk.mSlug);
36+
addTranscriptsHandler(data.talk.id);
37+
}
38+
};
39+
request.send();
40+
var $languages = document.querySelector('#languages ul');
41+
var languageTemplate = '<li data-lang="{{code}}">{{name}}</li>';
42+
var addLanguage, setSelected;
43+
var selected = [];
44+
setSelected = function(e) {
45+
var li, languageCode, length, index;
46+
li= e.target;
47+
languageCode = li.dataset.code;
48+
length = selected.length;
49+
index = selected.indexOf(languageCode);
50+
if (length < 2) {
51+
li.classList.toggle('selected');
52+
index === -1 ? selected.push(languageCode) : selected.splice(index, 1);
53+
} else if (length === 2) {
54+
li.classList.remove('selected');
55+
if (index !== -1) selected.splice(index, 1);
56+
}
57+
};
58+
59+
addLanguage = function(language) {
60+
var li = document.createElement('li');
61+
li.dataset.code = language.code;
62+
li.innerHTML = language.name;
63+
li.addEventListener('click', setSelected);
64+
$languages.appendChild(li);
65+
}
66+
67+
var downloadUrl = "http://download.ted.com/talks/";
68+
var mkVideoUrl = function(slug, quality) {
69+
return downloadUrl + slug + '-' + quality + '.mp4';
70+
};
71+
var addVideoDownloads = function (mediaSlug) {
72+
var template = [
73+
'<ul><li>',
74+
'<a href="{{720p}}" title="Right click to save (1280x720)" target="_blank">720p</a>',
75+
'</li><li>',
76+
'<a href="{{480p}}" title="Right click to save (854x480)" target="_blank">480p</a>',
77+
'</li><li>',
78+
'<a href="{{360p}}" title="Right click to save (640x360)" target="_blank">360p</a>',
79+
'</li><li>',
80+
'<a href="{{288p}}" title="Right click to save (512x288)" target="_blank">288p</a>',
81+
'</li></ul>'
82+
].join('\n');
83+
$video = document.getElementById('video');
84+
$video.innerHTML = template.replace('{{720p}}', mkVideoUrl(mediaSlug, '1500k'))
85+
.replace('{{480p}}', mkVideoUrl(mediaSlug, '950k'))
86+
.replace('{{360p}}', mkVideoUrl(mediaSlug, '600k'))
87+
.replace('{{288p}}', mkVideoUrl(mediaSlug, '320k'));
88+
};
89+
90+
var mkTranscriptUrl = function(tid, format) {
91+
var queryString = '';
92+
if (selected.length === 0) {
93+
queryString = 'lang=en';
94+
} else {
95+
queryString = selected.map(function(code) {
96+
return 'lang=' + code
97+
}).join('&')
98+
}
99+
return '/api/talks/' + tid + '/downloads/transcripts/' + format + '?' + queryString;
100+
}
101+
102+
var addTranscriptsHandler = function(tid) {
103+
document.querySelector('#subtitles ul').addEventListener('click', function(e) {
104+
if (e.target.id) {
105+
window.location = mkTranscriptUrl(tid, e.target.id);
106+
}
107+
});
108+
};
109+
};
110+
111+
var searchPageHandler = function(params) {
112+
var request = new XMLHttpRequest();
113+
request.open('GET', '/api/search?q=' + params.q, true);
114+
115+
request.onload = function() {
116+
if (request.status >= 200 && request.status < 400) {
117+
var data = JSON.parse(request.responseText);
118+
console.log(data);
119+
data.forEach(addSearchResult);
120+
}
121+
};
122+
request.send();
123+
124+
var addSearchResult;
125+
var $result;
126+
$result = document.getElementById('result');
127+
addSearchResult = function(talk) {
128+
var template = [
129+
'<a href="/talks/{{slug}}"><img src="{{src}}"></a>',
130+
'<h3><a href="/talks/{{slug}}">{{title}}</a></h3>',
131+
'<p>{{description}}</p>',
132+
].join('\n');
133+
var li = document.createElement('li');
134+
li.innerHTML = template.replace('{{slug}}', talk.slug)
135+
.replace('{{src}}', talk.image)
136+
.replace('{{title}}', talk.name)
137+
.replace('{{description}}', talk.description);
138+
$result.appendChild(li);
139+
}
140+
};
141+
142+
var $container = document.getElementById('container');
143+
var routes = {
144+
'/': function() {
145+
$container.innerHTML = [
146+
'<div id="homepage">',
147+
'<form id="search" method="GET" action="/search">',
148+
'<input type="text" name="q" required>',
149+
'<input type="submit">',
150+
'</form>',
151+
'<div id="talks"></div>',
152+
'</div>'
153+
].join('\n');
154+
homepageHandler();
155+
},
156+
'/talks/:slug': function(slug) {
157+
$container.innerHTML = [
158+
'<div id="talk">',
159+
'<div id="downloads">',
160+
'<div id="video"></div>',
161+
'<div id="subtitles">',
162+
'<ul><li>',
163+
'<a id="srt">SRT</a>',
164+
'</li><li>',
165+
'<a id="txt">TXT</a>',
166+
'</li><li>',
167+
'<a id="lrc">LRC</a>',
168+
'</li><ul>',
169+
'</div>',
170+
'</div>',
171+
'<div id="languages"><ul></ul></div>',
172+
'</div>'
173+
].join('\n');
174+
talkPageHandler(slug);
175+
},
176+
'/search': function() {
177+
var querys = window.location.search.split('?')[1].split('&');
178+
var params = {};
179+
querys.forEach(function(q) {
180+
var qs = q.split('=');
181+
params[qs[0]] = qs[1];
182+
});
183+
$container.innerHTML = [
184+
'<div id="search-page">',
185+
'<ul id="result"></ul>',
186+
'</div>'
187+
].join('\n');
188+
searchPageHandler(params);
189+
}
190+
};
191+
192+
var router = Router(routes).configure({html5history: true});
193+
194+
router.notfound = function() {
195+
console.log('not found');
196+
};
197+
198+
router.init();

0 commit comments

Comments
 (0)