Skip to content

Commit f0cfc19

Browse files
committed
a new approach for the ui
1 parent cc85486 commit f0cfc19

34 files changed

+2246
-146
lines changed

.stylelintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ rules:
1010
declaration-colon-newline-after: null
1111
selector-list-comma-newline-after: null
1212
value-list-comma-newline-after: null
13+
at-rule-no-unknown: null

app/archive.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ export default class Archive {
6262
return true;
6363
}
6464

65-
remove(index) {
66-
this.files.splice(index, 1);
65+
remove(file) {
66+
const index = this.files.indexOf(file);
67+
if (index > -1) {
68+
this.files.splice(index, 1);
69+
}
6770
}
6871
}

app/dragManager.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ export default function(state, emitter) {
33
document.body.addEventListener('dragover', event => {
44
if (state.route === '/') {
55
event.preventDefault();
6-
const files = document.querySelector('.uploadedFilesWrapper');
7-
files.classList.add('uploadArea--noEvents');
6+
// const files = document.querySelector('.uploadedFilesWrapper');
7+
// files.classList.add('uploadArea--noEvents');
88
}
99
});
1010
document.body.addEventListener('drop', event => {
1111
if (state.route === '/' && !state.uploading) {
1212
event.preventDefault();
13-
document
14-
.querySelector('.uploadArea')
15-
.classList.remove('uploadArea--dragging');
13+
// document
14+
// .querySelector('.uploadArea')
15+
// .classList.remove('uploadArea--dragging');
1616

1717
const files = Array.from(event.dataTransfer.files);
1818

app/fileManager.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,11 @@ export default function(state, emitter) {
6666
metrics.changedDownloadLimit(file);
6767
});
6868

69-
emitter.on('removeUpload', async ({ index }) => {
70-
state.archive.remove(index);
69+
emitter.on('removeUpload', file => {
70+
state.archive.remove(file);
71+
if (state.archive.numFiles === 0) {
72+
state.archive = null;
73+
}
7174
render();
7275
});
7376

@@ -86,6 +89,7 @@ export default function(state, emitter) {
8689
} catch (e) {
8790
state.raven.captureException(e);
8891
}
92+
render();
8993
});
9094

9195
emitter.on('cancel', () => {
@@ -149,15 +153,26 @@ export default function(state, emitter) {
149153
if (password) {
150154
emitter.emit('password', { password, file: ownedFile });
151155
}
152-
153-
const cancelBtn = document.getElementById('cancel-upload');
154-
if (cancelBtn) {
155-
cancelBtn.hidden = 'hidden';
156-
}
157-
if (document.querySelector('.page')) {
158-
await delay(1000);
159-
}
160-
emitter.emit('pushState', `/share/${ownedFile.id}`);
156+
state.animation = () => {
157+
const x = document.querySelector('.foo');
158+
const y = x.previousElementSibling;
159+
x.animate(
160+
[
161+
{ transform: `translateY(-${y.getBoundingClientRect().height}px)` },
162+
{ transform: 'translateY(0)' }
163+
],
164+
{
165+
duration: 400,
166+
easing: 'ease'
167+
}
168+
);
169+
y.animate([{ opacity: 0 }, { opacity: 1 }], {
170+
delay: 300,
171+
duration: 100,
172+
fill: 'both'
173+
});
174+
};
175+
// emitter.emit('pushState', `/share/${ownedFile.id}`);
161176
} catch (err) {
162177
if (err.message === '0') {
163178
//cancelled. do nothing
@@ -176,6 +191,7 @@ export default function(state, emitter) {
176191
state.password = '';
177192
state.uploading = false;
178193
state.transfer = null;
194+
render();
179195
}
180196
});
181197

app/main.css

Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,81 @@
1-
@import './base.css';
2-
@import './pages/share/share.css';
3-
@import './pages/signin/signin.css';
4-
@import './pages/uploads/uploads.css';
5-
@import './pages/unsupported/unsupported.css';
6-
@import './templates/archiveTile/archiveTile.css';
7-
@import './templates/controlArea/controlArea.css';
8-
@import './templates/downloadButton/downloadButton.css';
9-
@import './templates/downloadPassword/downloadPassword.css';
10-
@import './templates/file/file.css';
11-
@import './templates/fileIcon/fileIcon.css';
12-
@import './templates/fileList/fileList.css';
13-
@import './templates/fileManager/fileManager.css';
14-
@import './templates/footer/footer.css';
15-
@import './templates/fxPromo/fxPromo.css';
16-
@import './templates/header/header.css';
17-
@import './templates/modal/modal.css';
18-
@import './templates/okDialog/okDialog.css';
19-
@import './templates/passwordInput/passwordInput.css';
20-
@import './templates/popup/popup.css';
21-
@import './templates/selectbox/selectbox.css';
22-
@import './templates/setPasswordSection/setPasswordSection.css';
23-
@import './templates/signupDialog/signupDialog.css';
24-
@import './templates/signupPromo/signupPromo.css';
25-
@import './templates/title/title.css';
26-
@import './templates/uploadedFile/uploadedFile.css';
27-
@import './templates/uploadedFileList/uploadedFileList.css';
28-
@import './templates/userAccount/userAccount.css';
1+
@import 'tailwindcss/preflight';
2+
@import 'tailwindcss/components';
3+
@import 'tailwindcss/utilities';
4+
5+
a {
6+
color: inherit;
7+
text-decoration: none;
8+
}
9+
10+
progress {
11+
@apply bg-grey-light;
12+
@apply rounded-sm;
13+
@apply w-full;
14+
@apply h-1;
15+
}
16+
17+
progress::-moz-progress-bar {
18+
@apply bg-blue;
19+
@apply rounded-sm;
20+
}
21+
22+
progress::-webkit-progress-bar {
23+
@apply bg-grey-light;
24+
@apply rounded-sm;
25+
@apply w-full;
26+
@apply h-1;
27+
}
28+
29+
progress::-webkit-progress-value {
30+
@apply bg-blue;
31+
@apply rounded-sm;
32+
}
33+
34+
.main {
35+
@apply bg-blue-lightest;
36+
37+
min-height: calc(100vh - 6rem);
38+
}
39+
40+
.header-logo {
41+
background-image: url('../assets/send_logo.svg');
42+
background-position: left;
43+
background-repeat: no-repeat;
44+
background-size: 2rem;
45+
padding-left: 2.5rem;
46+
text-decoration: none;
47+
}
48+
49+
.feedback-link {
50+
background-color: #000;
51+
background-image: url('../assets/feedback.svg');
52+
background-position: 0.125rem 0.25rem;
53+
background-repeat: no-repeat;
54+
background-size: 1.125rem;
55+
color: #fff;
56+
display: block;
57+
font-size: 0.75rem;
58+
line-height: 0.75rem;
59+
padding: 0.375rem 0.375rem 0.375rem 1.25rem;
60+
text-indent: 0.125rem;
61+
white-space: nowrap;
62+
}
63+
64+
.bg-shades {
65+
background-color: rgba(0, 0, 0, 0.7);
66+
}
67+
68+
@screen md {
69+
.main {
70+
@apply flex-1;
71+
@apply self-center;
72+
@apply bg-white;
73+
@apply shadow-md;
74+
@apply m-auto;
75+
76+
min-width: 30rem;
77+
max-width: 60rem;
78+
min-height: 30rem;
79+
max-height: 38rem;
80+
}
81+
}

app/main.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ import User from './user';
3434
window.appState = state;
3535
window.appEmit = emitter.emit.bind(emitter);
3636
let unsupportedReason = null;
37+
38+
emitter.on('render', () => {
39+
if (state.animation) {
40+
window.requestAnimationFrame(() => {
41+
state.animation();
42+
state.animation = null;
43+
});
44+
}
45+
});
3746
if (
3847
// Firefox < 50
3948
/firefox/i.test(navigator.userAgent) &&

app/routes.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const choo = require('choo');
2+
const html = require('choo/html');
3+
const nanotiming = require('nanotiming');
4+
const download = require('./ui/download');
5+
const footer = require('./ui/footer');
6+
const fxPromo = require('./ui/fxPromo');
7+
const modal = require('./ui/modal');
8+
const header = require('./ui/header');
9+
10+
nanotiming.disabled = true;
11+
12+
function banner(state, emit) {
13+
if (state.promo && !state.route.startsWith('/unsupported/')) {
14+
return fxPromo(state, emit);
15+
}
16+
}
17+
18+
function body(main) {
19+
return function(state, emit) {
20+
const b = html`<body class="flex flex-col font-sans bg-white md:h-screen md:bg-grey-lightest">
21+
${state.modal && modal(state, emit)}
22+
${banner(state, emit)}
23+
${header(state, emit)}
24+
${main(state, emit)}
25+
${footer(state)}
26+
</body>`;
27+
if (state.layout) {
28+
// server side only
29+
return state.layout(state, b);
30+
}
31+
return b;
32+
};
33+
}
34+
35+
module.exports = function() {
36+
const app = choo();
37+
app.route('/', body(require('./ui/welcome')));
38+
app.route('/download/:id', body(download));
39+
app.route('/download/:id/:key', body(download));
40+
app.route('/unsupported/:reason', body(require('./ui/unsupported')));
41+
app.route('/legal', body(require('./ui/legal')));
42+
app.route('/error', body(require('./ui/error')));
43+
app.route('/blank', body(require('./ui/blank')));
44+
app.route('/oauth', async function(state, emit) {
45+
try {
46+
await state.user.finishLogin(state.query.code, state.query.state);
47+
emit('replaceState', '/');
48+
} catch (e) {
49+
emit('replaceState', '/error');
50+
setTimeout(() => emit('render'));
51+
}
52+
});
53+
app.route('*', body(require('./ui/notFound')));
54+
return app;
55+
};

app/routes/download.js

Lines changed: 0 additions & 30 deletions
This file was deleted.

app/routes/index.js

Lines changed: 0 additions & 65 deletions
This file was deleted.

0 commit comments

Comments
 (0)