mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-12-24 04:43:08 +02:00
wip
This commit is contained in:
parent
3a39a36bed
commit
2a3a5d4b50
35 changed files with 402 additions and 367 deletions
|
@ -114,13 +114,13 @@
|
|||
this.cancel = () => {
|
||||
this.api('auth/deny', {
|
||||
token: @session.token
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.trigger('denied');
|
||||
|
||||
this.accept = () => {
|
||||
this.api('auth/accept', {
|
||||
token: @session.token
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.trigger('accepted');
|
||||
</script>
|
||||
</mk-form>
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
if @session.app.is_authorized
|
||||
this.api('auth/accept', {
|
||||
token: @session.token
|
||||
.then =>
|
||||
}).then(() => {
|
||||
@accepted!
|
||||
else
|
||||
this.state = 'waiting'
|
||||
|
|
8
src/web/app/common/scripts/contains.js
Normal file
8
src/web/app/common/scripts/contains.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
module.exports = function(parent, child) {
|
||||
let node = child.parentNode;
|
||||
while (node) {
|
||||
if (node == parent) return true;
|
||||
node = node.parentNode;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -126,7 +126,7 @@
|
|||
this.api('signin', {
|
||||
username: this.refs.username.value
|
||||
password: this.refs.password.value
|
||||
.then =>
|
||||
}).then(() => {
|
||||
location.reload();
|
||||
.catch =>
|
||||
alert 'something happened'
|
||||
|
|
|
@ -277,11 +277,11 @@
|
|||
username: username,
|
||||
password: password,
|
||||
'g-recaptcha-response': grecaptcha.getResponse()
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.api('signin', {
|
||||
username: username
|
||||
password: password
|
||||
.then =>
|
||||
}).then(() => {
|
||||
location.href = CONFIG.url
|
||||
.catch =>
|
||||
alert '何らかの原因によりアカウントの作成に失敗しました。再度お試しください。'
|
||||
|
|
|
@ -6,100 +6,92 @@
|
|||
display block
|
||||
width 256px
|
||||
height 256px
|
||||
|
||||
</style>
|
||||
<script>
|
||||
class Vec2 {
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
this.on('mount', () => {
|
||||
@draw!
|
||||
this.clock = setInterval @draw, 1000ms
|
||||
this.draw()
|
||||
this.clock = setInterval(this.draw, 1000);
|
||||
});
|
||||
|
||||
this.on('unmount', () => {
|
||||
clearInterval @clock
|
||||
clearInterval(this.clock);
|
||||
});
|
||||
|
||||
this.draw = () => {
|
||||
const now = new Date();
|
||||
s = now.get-seconds!
|
||||
m = now.getMinutes()
|
||||
h = now.getHours()
|
||||
const s = now.getSeconds();
|
||||
const m = now.getMinutes();
|
||||
const h = now.getHours();
|
||||
|
||||
vec2 = (x, y) ->
|
||||
this.x = x
|
||||
this.y = y
|
||||
const ctx = this.refs.canvas.getContext('2d');
|
||||
const canvW = this.refs.canvas.width;
|
||||
const canvH = this.refs.canvas.height;
|
||||
ctx.clearRect(0, 0, canvW, canvH);
|
||||
|
||||
ctx = this.refs.canvas.get-context '2d'
|
||||
canv-w = this.refs.canvas.width
|
||||
canv-h = this.refs.canvas.height
|
||||
ctx.clear-rect 0, 0, canv-w, canv-h
|
||||
{ // 背景
|
||||
const center = Math.min((canvW / 2), (canvH / 2));
|
||||
const lineStart = center * 0.90;
|
||||
const shortLineEnd = center * 0.87;
|
||||
const longLineEnd = center * 0.84;
|
||||
for (let i = 0; i < 60; i++) {
|
||||
const angle = Math.PI * i / 30;
|
||||
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = 1;
|
||||
ctx.moveTo((canv-w / 2) + uv.x * lineStart, (canv-h / 2) + uv.y * lineStart);
|
||||
if (i % 5 == 0) {
|
||||
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
|
||||
ctx.lineTo((canv-w / 2) + uv.x * longLineEnd, (canv-h / 2) + uv.y * longLineEnd);
|
||||
} else {
|
||||
ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
|
||||
ctx.lineTo((canv-w / 2) + uv.x * shortLineEnd, (canv-h / 2) + uv.y * shortLineEnd);
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
// 背景
|
||||
center = (Math.min (canv-w / 2), (canv-h / 2))
|
||||
line-start = center * 0.90
|
||||
line-end-short = center * 0.87
|
||||
line-end-long = center * 0.84
|
||||
for i from 0 to 59 by 1
|
||||
angle = Math.PI * i / 30
|
||||
uv = new vec2 (Math.sin angle), (-Math.cos angle)
|
||||
ctx.begin-path!
|
||||
ctx.line-width = 1
|
||||
ctx.move-to do
|
||||
(canv-w / 2) + uv.x * line-start
|
||||
(canv-h / 2) + uv.y * line-start
|
||||
if i % 5 == 0
|
||||
ctx.stroke-style = 'rgba(255, 255, 255, 0.2)'
|
||||
ctx.line-to do
|
||||
(canv-w / 2) + uv.x * line-end-long
|
||||
(canv-h / 2) + uv.y * line-end-long
|
||||
else
|
||||
ctx.stroke-style = 'rgba(255, 255, 255, 0.1)'
|
||||
ctx.line-to do
|
||||
(canv-w / 2) + uv.x * line-end-short
|
||||
(canv-h / 2) + uv.y * line-end-short
|
||||
ctx.stroke!
|
||||
{ // 分
|
||||
const angle = Math.PI * (m + s / 60) / 30;
|
||||
const length = Math.min(canvW, canvH) / 2.6;
|
||||
const uv = new vec2(Math.sin(angle), -Math.cos(angle));
|
||||
ctx.beginPath();
|
||||
ctx.strokeStyle = '#ffffff';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
|
||||
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// 分
|
||||
angle = Math.PI * (m + s / 60) / 30
|
||||
length = (Math.min canv-w, canv-h) / 2.6
|
||||
uv = new vec2 (Math.sin angle), (-Math.cos angle)
|
||||
ctx.begin-path!
|
||||
ctx.stroke-style = '#ffffff'
|
||||
ctx.line-width = 2
|
||||
ctx.move-to do
|
||||
(canv-w / 2) - uv.x * length / 5
|
||||
(canv-h / 2) - uv.y * length / 5
|
||||
ctx.line-to do
|
||||
(canv-w / 2) + uv.x * length
|
||||
(canv-h / 2) + uv.y * length
|
||||
ctx.stroke!
|
||||
{ // 時
|
||||
const angle = Math.PI * (h % 12 + m / 60) / 6;
|
||||
const length = Math.min(canvW, canvH) / 4;
|
||||
const uv = new vec2(Math.sin(angle), -Math.cos(angle));
|
||||
ctx.beginPath();
|
||||
ctx.strokeStyle = CONFIG.themeColor;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
|
||||
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// 時
|
||||
angle = Math.PI * (h % 12 + m / 60) / 6
|
||||
length = (Math.min canv-w, canv-h) / 4
|
||||
uv = new vec2 (Math.sin angle), (-Math.cos angle)
|
||||
ctx.begin-path!
|
||||
#ctx.stroke-style = '#ffffff'
|
||||
ctx.stroke-style = CONFIG.theme-color
|
||||
ctx.line-width = 2
|
||||
ctx.move-to do
|
||||
(canv-w / 2) - uv.x * length / 5
|
||||
(canv-h / 2) - uv.y * length / 5
|
||||
ctx.line-to do
|
||||
(canv-w / 2) + uv.x * length
|
||||
(canv-h / 2) + uv.y * length
|
||||
ctx.stroke!
|
||||
|
||||
// 秒
|
||||
angle = Math.PI * s / 30
|
||||
length = (Math.min canv-w, canv-h) / 2.6
|
||||
uv = new vec2 (Math.sin angle), (-Math.cos angle)
|
||||
ctx.begin-path!
|
||||
ctx.stroke-style = 'rgba(255, 255, 255, 0.5)'
|
||||
ctx.line-width = 1
|
||||
ctx.move-to do
|
||||
(canv-w / 2) - uv.x * length / 5
|
||||
(canv-h / 2) - uv.y * length / 5
|
||||
ctx.line-to do
|
||||
(canv-w / 2) + uv.x * length
|
||||
(canv-h / 2) + uv.y * length
|
||||
ctx.stroke!
|
||||
{ // 秒
|
||||
const angle = Math.PI * s / 30;
|
||||
const length = Math.min(canvW, canvH) / 2.6;
|
||||
const uv = new vec2(Math.sin(angle), -Math.cos(angle));
|
||||
ctx.beginPath();
|
||||
ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
|
||||
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
|
||||
ctx.stroke();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</mk-analog-clock>
|
||||
|
|
|
@ -80,108 +80,118 @@
|
|||
|
||||
</style>
|
||||
<script>
|
||||
const contains = require('../../common/scripts/contains');
|
||||
|
||||
this.mixin('api');
|
||||
|
||||
this.q = this.opts.q
|
||||
this.textarea = this.opts.textarea
|
||||
this.loading = true
|
||||
this.users = []
|
||||
this.select = -1
|
||||
this.q = this.opts.q;
|
||||
this.textarea = this.opts.textarea;
|
||||
this.fetching = true;
|
||||
this.users = [];
|
||||
this.select = -1;
|
||||
|
||||
this.on('mount', () => {
|
||||
@textarea.addEventListener 'keydown' this.on-keydown
|
||||
this.textarea.addEventListener('keydown', this.onKeydown);
|
||||
|
||||
all = document.query-selector-all 'body *'
|
||||
Array.prototype.forEach.call all, (el) =>
|
||||
el.addEventListener 'mousedown' @mousedown
|
||||
document.querySelectorAll('body *').forEach(el => {
|
||||
el.addEventListener('mousedown', this.mousedown);
|
||||
});
|
||||
|
||||
this.api('users/search_by_username', {
|
||||
query: @q
|
||||
limit: 30users
|
||||
}).then((users) => {
|
||||
this.users = users
|
||||
this.loading = false
|
||||
this.update();
|
||||
.catch (err) =>
|
||||
console.error err
|
||||
query: this.q,
|
||||
limit: 30
|
||||
}).then(users => {
|
||||
this.update({
|
||||
fetching: false,
|
||||
users: users
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
this.on('unmount', () => {
|
||||
@textarea.removeEventListener 'keydown' this.on-keydown
|
||||
this.textarea.removeEventListener('keydown', this.onKeydown);
|
||||
|
||||
all = document.query-selector-all 'body *'
|
||||
Array.prototype.forEach.call all, (el) =>
|
||||
el.removeEventListener 'mousedown' @mousedown
|
||||
document.querySelectorAll('body *').forEach(el => {
|
||||
el.removeEventListener('mousedown', this.mousedown);
|
||||
});
|
||||
});
|
||||
|
||||
this.mousedown = (e) => {
|
||||
if (!contains this.root, e.target) and (this.root != e.target)
|
||||
@close();
|
||||
this.mousedown = e => {
|
||||
if (!contains(this.root, e.target) && (this.root != e.target)) this.close();
|
||||
};
|
||||
|
||||
this.on-click = (e) => {
|
||||
@complete e.item
|
||||
this.onClick = e => {
|
||||
this.complete(e.item);
|
||||
};
|
||||
|
||||
this.on-keydown = (e) => {
|
||||
key = e.which
|
||||
switch (key)
|
||||
| 10, 13 => // Key[ENTER]
|
||||
if @select != -1
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@complete this.users[@select]
|
||||
else
|
||||
@close();
|
||||
| 27 => // Key[ESC]
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@close();
|
||||
| 38 => // Key[↑]
|
||||
if @select != -1
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@select-prev!
|
||||
else
|
||||
@close();
|
||||
| 9, 40 => // Key[TAB] or Key[↓]
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@select-next!
|
||||
| _ =>
|
||||
@close();
|
||||
this.onKeydown = e => {
|
||||
const cancel = () => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
this.select-next = () => {
|
||||
@select++
|
||||
switch (e.which) {
|
||||
case 10: // [ENTER]
|
||||
case 13: // [ENTER]
|
||||
if (this.select !== -1) {
|
||||
cancel();
|
||||
this.complete(this.users[this.select]);
|
||||
} else {
|
||||
this.close();
|
||||
}
|
||||
break;
|
||||
|
||||
if @select >= this.users.length
|
||||
this.select = 0
|
||||
case 27: // [ESC]
|
||||
cancel();
|
||||
this.close();
|
||||
break;
|
||||
|
||||
@apply-select!
|
||||
case 38: // [↑]
|
||||
if (this.select !== -1) {
|
||||
cancel();
|
||||
this.selectPrev();
|
||||
} else {
|
||||
this.close();
|
||||
}
|
||||
break;
|
||||
|
||||
this.select-prev = () => {
|
||||
@select--
|
||||
case 9: // [TAB]
|
||||
case 40: // [↓]
|
||||
cancel();
|
||||
this.selectNext();
|
||||
break;
|
||||
|
||||
if @select < 0
|
||||
this.select = this.users.length - 1
|
||||
default:
|
||||
this.close();
|
||||
}
|
||||
};
|
||||
|
||||
@apply-select!
|
||||
this.selectNext = () => {
|
||||
if (++this.select >= this.users.length) this.select = 0;
|
||||
this.applySelect();
|
||||
};
|
||||
|
||||
this.apply-select = () => {
|
||||
this.refs.users.children.forEach (el) =>
|
||||
el.remove-attribute 'data-selected'
|
||||
this.selectPrev = () => {
|
||||
if (--this.select < 0) this.select = this.users.length - 1;
|
||||
this.applySelect();
|
||||
};
|
||||
|
||||
this.refs.users.children[@select].setAttribute 'data-selected' \true
|
||||
this.refs.users.children[@select].focus();
|
||||
this.applySelect = () => {
|
||||
this.refs.users.children.forEach(el => {
|
||||
el.removeAttribute('data-selected');
|
||||
});
|
||||
|
||||
this.complete = (user) => {
|
||||
this.opts.complete user
|
||||
this.refs.users.children[this.select].setAttribute('data-selected', 'true');
|
||||
this.refs.users.children[this.select].focus();
|
||||
};
|
||||
|
||||
this.complete = user => {
|
||||
this.opts.complete(user);
|
||||
};
|
||||
|
||||
this.close = () => {
|
||||
this.opts.close();
|
||||
};
|
||||
|
||||
function contains(parent, child)
|
||||
node = child.parentNode
|
||||
while node?
|
||||
if node == parent
|
||||
return true
|
||||
node = node.parentNode
|
||||
return false
|
||||
</script>
|
||||
</mk-autocomplete-suggestion>
|
||||
|
|
|
@ -106,21 +106,21 @@
|
|||
if this.user.is_following
|
||||
this.api('following/delete', {
|
||||
user_id: this.user.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.user.is_following = false
|
||||
.catch (err) ->
|
||||
console.error err
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.wait = false
|
||||
this.update();
|
||||
else
|
||||
this.api('following/create', {
|
||||
user_id: this.user.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.user.is_following = true
|
||||
.catch (err) ->
|
||||
console.error err
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.wait = false
|
||||
this.update();
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<mk-contextmenu><yield />
|
||||
<mk-contextmenu>
|
||||
<yield />
|
||||
<style>
|
||||
:scope
|
||||
$width = 240px
|
||||
|
@ -94,46 +95,45 @@
|
|||
|
||||
</style>
|
||||
<script>
|
||||
this.root.addEventListener 'contextmenu' (e) =>
|
||||
const contains = require('../../common/scripts/contains');
|
||||
|
||||
this.root.addEventListener('contextmenu', e => {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
this.mousedown = (e) => {
|
||||
this.mousedown = e => {
|
||||
e.preventDefault();
|
||||
if (!contains this.root, e.target) and (this.root != e.target)
|
||||
@close();
|
||||
return false
|
||||
if (!contains(this.root, e.target) && (this.root != e.target)) this.close();
|
||||
return false;
|
||||
};
|
||||
|
||||
this.open = (pos) => {
|
||||
all = document.query-selector-all 'body *'
|
||||
Array.prototype.forEach.call all, (el) =>
|
||||
el.addEventListener 'mousedown' @mousedown
|
||||
this.root.style.display = 'block'
|
||||
this.root.style.left = pos.x + 'px'
|
||||
this.root.style.top = pos.y + 'px'
|
||||
this.open = pos => {
|
||||
document.querySelectorAll('body *').forEach(el => {
|
||||
el.addEventListener('mousedown', this.mousedown);
|
||||
});
|
||||
|
||||
Velocity(this.root, 'finish' true
|
||||
Velocity(this.root, { opacity: 0 } 0ms
|
||||
this.root.style.display = 'block';
|
||||
this.root.style.left = pos.x + 'px';
|
||||
this.root.style.top = pos.y + 'px';
|
||||
|
||||
Velocity(this.root, 'finish', true);
|
||||
Velocity(this.root, { opacity: 0 }, 0);
|
||||
Velocity(this.root, {
|
||||
opacity: 1
|
||||
}, {
|
||||
queue: false
|
||||
duration: 100ms
|
||||
easing: 'linear'
|
||||
}
|
||||
queue: false,
|
||||
duration: 100,
|
||||
easing: 'linear'
|
||||
});
|
||||
};
|
||||
|
||||
this.close = () => {
|
||||
all = document.query-selector-all 'body *'
|
||||
Array.prototype.forEach.call all, (el) =>
|
||||
el.removeEventListener 'mousedown' @mousedown
|
||||
document.querySelectorAll('body *').forEach(el => {
|
||||
el.removeEventListener('mousedown', this.mousedown);
|
||||
});
|
||||
|
||||
this.trigger('closed');
|
||||
this.unmount();
|
||||
|
||||
function contains(parent, child)
|
||||
node = child.parentNode
|
||||
while (node != null)
|
||||
if (node == parent)
|
||||
return true
|
||||
node = node.parentNode
|
||||
return false
|
||||
};
|
||||
</script>
|
||||
</mk-contextmenu>
|
||||
|
|
|
@ -79,69 +79,72 @@
|
|||
|
||||
</style>
|
||||
<script>
|
||||
this.can-through = if opts.can-through? then opts.can-through else true
|
||||
this.opts.buttons.forEach (button) =>
|
||||
button._onclick = =>
|
||||
if button.onclick?
|
||||
button.onclick();
|
||||
@close();
|
||||
this.canThrough = opts.canThrough != null ? opts.canThrough : true;
|
||||
this.opts.buttons.forEach(button => {
|
||||
button._onclick = () => {
|
||||
if (button.onclick) button.onclick();
|
||||
this.close();
|
||||
};
|
||||
});
|
||||
|
||||
this.on('mount', () => {
|
||||
this.refs.header.innerHTML = this.opts.title
|
||||
this.refs.body.innerHTML = this.opts.text
|
||||
this.refs.header.innerHTML = this.opts.title;
|
||||
this.refs.body.innerHTML = this.opts.text;
|
||||
|
||||
this.refs.bg.style.pointer-events = 'auto'
|
||||
Velocity(this.refs.bg, 'finish' true
|
||||
this.refs.bg.style.pointerEvents = 'auto';
|
||||
Velocity(this.refs.bg, 'finish', true);
|
||||
Velocity(this.refs.bg, {
|
||||
opacity: 1
|
||||
}, {
|
||||
queue: false
|
||||
duration: 100ms
|
||||
easing: 'linear'
|
||||
}
|
||||
queue: false,
|
||||
duration: 100,
|
||||
easing: 'linear'
|
||||
});
|
||||
|
||||
Velocity(this.refs.main, {
|
||||
opacity: 0
|
||||
opacity: 0,
|
||||
scale: 1.2
|
||||
}, {
|
||||
duration: 0
|
||||
}
|
||||
});
|
||||
Velocity(this.refs.main, {
|
||||
opacity: 1
|
||||
opacity: 1,
|
||||
scale: 1
|
||||
}, {
|
||||
duration: 300ms
|
||||
duration: 300,
|
||||
easing: [ 0, 0.5, 0.5, 1 ]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.close = () => {
|
||||
this.refs.bg.style.pointer-events = 'none'
|
||||
Velocity(this.refs.bg, 'finish' true
|
||||
this.refs.bg.style.pointerEvents = 'none';
|
||||
Velocity(this.refs.bg, 'finish', true);
|
||||
Velocity(this.refs.bg, {
|
||||
opacity: 0
|
||||
}, {
|
||||
queue: false
|
||||
duration: 300ms
|
||||
queue: false,
|
||||
duration: 300,
|
||||
easing: 'linear'
|
||||
}
|
||||
});
|
||||
|
||||
this.refs.main.style.pointer-events = 'none'
|
||||
Velocity(this.refs.main, 'finish' true
|
||||
this.refs.main.style.pointerEvents = 'none';
|
||||
Velocity(this.refs.main, 'finish', true);
|
||||
Velocity(this.refs.main, {
|
||||
opacity: 0
|
||||
opacity: 0,
|
||||
scale: 0.8
|
||||
}, {
|
||||
queue: false
|
||||
duration: 300ms
|
||||
easing: [ 0.5, -0.5, 1, 0.5 ]
|
||||
complete: =>
|
||||
this.unmount();
|
||||
}
|
||||
queue: false,
|
||||
duration: 300,
|
||||
easing: [ 0.5, -0.5, 1, 0.5 ],
|
||||
complete: () => this.unmount()
|
||||
});
|
||||
};
|
||||
|
||||
this.bg-click = () => {
|
||||
if @can-through
|
||||
if this.opts.on-through?
|
||||
this.opts.on-through!
|
||||
@close();
|
||||
this.bgClick = () => {
|
||||
if (this.canThrough) {
|
||||
if (this.opts.onThrough) this.opts.onThrough();
|
||||
this.close();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</mk-dialog>
|
||||
|
|
|
@ -408,7 +408,7 @@
|
|||
this.api('drive/files/update', {
|
||||
file_id: file
|
||||
folder_id: if this.folder? then this.folder.id else null
|
||||
.then =>
|
||||
}).then(() => {
|
||||
// something
|
||||
.catch (err, text-status) =>
|
||||
console.error err
|
||||
|
@ -425,7 +425,7 @@
|
|||
this.api('drive/folders/update', {
|
||||
folder_id: folder
|
||||
parent_id: if this.folder? then this.folder.id else null
|
||||
.then =>
|
||||
}).then(() => {
|
||||
// something
|
||||
.catch (err) =>
|
||||
if err == 'detected-circular-definition'
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
this.api('drive/files/update', {
|
||||
file_id: this.file.id
|
||||
name: name
|
||||
.then =>
|
||||
}).then(() => {
|
||||
// something
|
||||
.catch (err) =>
|
||||
console.error err
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
this.api('drive/folders/update', {
|
||||
folder_id: this.folder.id
|
||||
name: name
|
||||
.then =>
|
||||
}).then(() => {
|
||||
// something
|
||||
.catch (err) =>
|
||||
console.error err
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
this.api('drive/files/update', {
|
||||
file_id: file
|
||||
folder_id: this.folder.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
// something
|
||||
.catch (err, text-status) =>
|
||||
console.error err
|
||||
|
@ -133,7 +133,7 @@
|
|||
this.api('drive/folders/update', {
|
||||
folder_id: folder
|
||||
parent_id: this.folder.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
// something
|
||||
.catch (err) =>
|
||||
if err == 'detected-circular-definition'
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
this.api('drive/files/update', {
|
||||
file_id: file
|
||||
folder_id: if this.folder? then this.folder.id else null
|
||||
.then =>
|
||||
}).then(() => {
|
||||
// something
|
||||
.catch (err, text-status) =>
|
||||
console.error err
|
||||
|
@ -87,7 +87,7 @@
|
|||
this.api('drive/folders/update', {
|
||||
folder_id: folder
|
||||
parent_id: if this.folder? then this.folder.id else null
|
||||
.then =>
|
||||
}).then(() => {
|
||||
// something
|
||||
.catch (err, text-status) =>
|
||||
console.error err
|
||||
|
|
|
@ -33,9 +33,5 @@
|
|||
40%
|
||||
transform scale(1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</mk-ellipsis-icon>
|
||||
|
|
|
@ -103,21 +103,21 @@
|
|||
if this.user.is_following
|
||||
this.api('following/delete', {
|
||||
user_id: this.user.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.user.is_following = false
|
||||
.catch (err) ->
|
||||
console.error err
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.wait = false
|
||||
this.update();
|
||||
else
|
||||
this.api('following/create', {
|
||||
user_id: this.user.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.user.is_following = true
|
||||
.catch (err) ->
|
||||
console.error err
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.wait = false
|
||||
this.update();
|
||||
</script>
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<mk-go-top>
|
||||
<button class="hidden" title="一番上へ"><i class="fa fa-angle-up"></i></button>
|
||||
<script>
|
||||
window.addEventListener 'load' this.on-scroll
|
||||
window.addEventListener 'scroll' this.on-scroll
|
||||
window.addEventListener 'resize' this.on-scroll
|
||||
|
||||
this.on-scroll = () => {
|
||||
if $ window .scroll-top! > 500px
|
||||
@remove-class 'hidden'
|
||||
else
|
||||
@add-class 'hidden'
|
||||
</script>
|
||||
</mk-go-top>
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
this.click = () => {
|
||||
dialog = document.body.appendChild(document.createElement('mk-image-dialog'));
|
||||
riot.mount dialog, do
|
||||
riot.mount dialog, do
|
||||
image: @image
|
||||
</script>
|
||||
</mk-images-viewer>
|
||||
|
|
|
@ -16,7 +16,6 @@ require('./crop-window.tag');
|
|||
require('./settings.tag');
|
||||
require('./settings-window.tag');
|
||||
require('./analog-clock.tag');
|
||||
require('./go-top.tag');
|
||||
require('./ui-header.tag');
|
||||
require('./ui-header-account.tag');
|
||||
require('./ui-header-notifications.tag');
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
<mk-input-dialog>
|
||||
<mk-window ref="window" is-modal={ true } width={ '500px' }><yield to="header"><i class="fa fa-i-cursor"></i>{ parent.title }</yield>
|
||||
<yield to="content">
|
||||
<div class="body">
|
||||
<input ref="text" oninput={ parent.update } onkeydown={ parent.onKeydown } placeholder={ parent.placeholder }/>
|
||||
</div>
|
||||
<div class="action">
|
||||
<button class="cancel" onclick={ parent.cancel }>キャンセル</button>
|
||||
<button class="ok" disabled={ !parent.allowEmpty && refs.text.value.length == 0 } onclick={ parent.ok }>決定</button>
|
||||
</div></yield>
|
||||
<mk-window ref="window" is-modal={ true } width={ '500px' }>
|
||||
<yield to="header">
|
||||
<i class="fa fa-i-cursor"></i>{ parent.title }
|
||||
</yield>
|
||||
<yield to="content">
|
||||
<div class="body">
|
||||
<input ref="text" oninput={ parent.update } onkeydown={ parent.onKeydown } placeholder={ parent.placeholder }/>
|
||||
</div>
|
||||
<div class="action">
|
||||
<button class="cancel" onclick={ parent.cancel }>キャンセル</button>
|
||||
<button class="ok" disabled={ !parent.allowEmpty && refs.text.value.length == 0 } onclick={ parent.ok }>決定</button>
|
||||
</div>
|
||||
</yield>
|
||||
</mk-window>
|
||||
<style>
|
||||
:scope
|
||||
|
@ -116,18 +120,17 @@
|
|||
|
||||
</style>
|
||||
<script>
|
||||
this.done = false
|
||||
this.done = false;
|
||||
|
||||
this.title = this.opts.title
|
||||
this.placeholder = this.opts.placeholder
|
||||
this.default = this.opts.default
|
||||
this.allow-empty = if this.opts.allow-empty? then this.opts.allow-empty else true
|
||||
this.title = this.opts.title;
|
||||
this.placeholder = this.opts.placeholder;
|
||||
this.default = this.opts.default;
|
||||
this.allowEmpty = this.opts.allowEmpty != null ? this.opts.allowEmpty : true;
|
||||
|
||||
this.on('mount', () => {
|
||||
this.text = this.refs.window.refs.text
|
||||
if @default?
|
||||
@text.value = @default
|
||||
@text.focus();
|
||||
this.text = this.refs.window.refs.text;
|
||||
if (this.default) this.text.value = this.default;
|
||||
this.text.focus();
|
||||
|
||||
this.refs.window.on('closing', () => {
|
||||
if @done
|
||||
|
@ -138,6 +141,7 @@
|
|||
|
||||
this.refs.window.on('closed', () => {
|
||||
this.unmount();
|
||||
});
|
||||
|
||||
this.cancel = () => {
|
||||
this.done = false
|
||||
|
@ -148,7 +152,7 @@
|
|||
this.done = true
|
||||
this.refs.window.close();
|
||||
|
||||
this.on-keydown = (e) => {
|
||||
this.onKeydown = (e) => {
|
||||
if e.which == 13 // Enter
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
|
|
@ -127,13 +127,13 @@
|
|||
if this.post.is_liked
|
||||
this.api('posts/likes/delete', {
|
||||
post_id: this.post.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.post.is_liked = false
|
||||
this.update();
|
||||
else
|
||||
this.api('posts/likes/create', {
|
||||
post_id: this.post.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.post.is_liked = true
|
||||
this.update();
|
||||
</script>
|
||||
|
|
|
@ -412,13 +412,13 @@
|
|||
if this.p.is_liked
|
||||
this.api('posts/likes/delete', {
|
||||
post_id: this.p.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.p.is_liked = false
|
||||
this.update();
|
||||
else
|
||||
this.api('posts/likes/create', {
|
||||
post_id: this.p.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.p.is_liked = true
|
||||
this.update();
|
||||
|
||||
|
|
|
@ -455,7 +455,7 @@
|
|||
.catch (err) =>
|
||||
console.error err
|
||||
@notify '投稿できませんでした'
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.wait = false
|
||||
this.update();
|
||||
|
||||
|
|
|
@ -127,14 +127,14 @@
|
|||
this.wait = true
|
||||
this.api('posts/create', {
|
||||
repost_id: this.opts.post.id
|
||||
text: if @quote then this.refs.text.value else undefined
|
||||
text: if this.quote then this.refs.text.value else undefined
|
||||
}).then((data) => {
|
||||
this.trigger('posted');
|
||||
@notify 'Repostしました!'
|
||||
.catch (err) =>
|
||||
console.error err
|
||||
@notify 'Repostできませんでした'
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.wait = false
|
||||
this.update();
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
window.addEventListener 'scroll' this.on-scroll
|
||||
|
||||
this.api('posts/search', {
|
||||
query: @query
|
||||
query: this.query
|
||||
}).then((posts) => {
|
||||
this.is-loading = false
|
||||
this.is-empty = posts.length == 0
|
||||
|
@ -68,7 +68,7 @@
|
|||
this.more-loading = true
|
||||
this.update();
|
||||
this.api('posts/search', {
|
||||
query: @query
|
||||
query: this.query
|
||||
page: this.page + 1
|
||||
}).then((posts) => {
|
||||
this.more-loading = false
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
<mk-sub-post-content>
|
||||
<div class="body"><a class="reply" if={ post.reply_to_id }><i class="fa fa-reply"></i></a><span ref="text"></span><a class="quote" if={ post.repost_id } href={ '/post:' + post.repost_id }>RP: ...</a></div>
|
||||
<div class="body">
|
||||
<a class="reply" if={ post.reply_to_id }>
|
||||
<i class="fa fa-reply"></i>
|
||||
</a>
|
||||
<span ref="text"></span>
|
||||
<a class="quote" if={ post.repost_id } href={ '/post:' + post.repost_id }>RP: ...</a>
|
||||
</div>
|
||||
<details if={ post.media }>
|
||||
<summary>({ post.media.length }つのメディア)</summary>
|
||||
<mk-images-viewer images={ post.media }></mk-images-viewer>
|
||||
|
@ -31,15 +37,17 @@
|
|||
this.mixin('text');
|
||||
this.mixin('user-preview');
|
||||
|
||||
this.post = this.opts.post
|
||||
this.post = this.opts.post;
|
||||
|
||||
this.on('mount', () => {
|
||||
if this.post.text?
|
||||
tokens = @analyze this.post.text
|
||||
this.refs.text.innerHTML = @compile tokens, false
|
||||
if (this.post.text) {
|
||||
const tokens = this.analyze(this.post.text);
|
||||
this.refs.text.innerHTML = this.compile(tokens, false);
|
||||
|
||||
this.refs.text.children.forEach (e) =>
|
||||
if e.tag-name == 'MK-URL'
|
||||
riot.mount e
|
||||
this.refs.text.children.forEach(e => {
|
||||
if (e.tagName == 'MK-URL') riot.mount(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</mk-sub-post-content>
|
||||
|
|
|
@ -324,7 +324,7 @@
|
|||
this.mixin('NotImplementedException');
|
||||
|
||||
this.post = this.opts.post;
|
||||
this.isRepost = this.post.repost != null && this.post.text == null;
|
||||
this.isRepost = this.post.repost && this.post.text == null;
|
||||
this.p = this.isRepost ? this.post.repost : this.post;
|
||||
|
||||
this.title = this.dateStringify(this.p.created_at);
|
||||
|
@ -354,58 +354,87 @@
|
|||
});
|
||||
|
||||
this.reply = () => {
|
||||
form = document.body.appendChild(document.createElement('mk-post-form-window'));
|
||||
riot.mount form, do
|
||||
riot.mount(document.body.appendChild(document.createElement('mk-post-form-window')), {
|
||||
reply: this.p
|
||||
});
|
||||
};
|
||||
|
||||
this.repost = () => {
|
||||
form = document.body.appendChild(document.createElement('mk-repost-form-window'));
|
||||
riot.mount form, do
|
||||
riot.mount(document.body.appendChild(document.createElement('mk-repost-form-window')), {
|
||||
post: this.p
|
||||
});
|
||||
};
|
||||
|
||||
this.like = () => {
|
||||
if this.p.is_liked
|
||||
if (this.p.is_liked) {
|
||||
this.api('posts/likes/delete', {
|
||||
post_id: this.p.id
|
||||
.then =>
|
||||
this.p.is_liked = false
|
||||
}).then(() => {
|
||||
this.p.is_liked = false;
|
||||
this.update();
|
||||
else
|
||||
});
|
||||
} else {
|
||||
this.api('posts/likes/create', {
|
||||
post_id: this.p.id
|
||||
.then =>
|
||||
this.p.is_liked = true
|
||||
}).then(() => {
|
||||
this.p.is_liked = true;
|
||||
this.update();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.toggle-detail = () => {
|
||||
this.is-detail-opened = !@is-detail-opened
|
||||
this.update();
|
||||
this.toggleDetail = () => {
|
||||
this.update({
|
||||
isDetailOpened: !this.isDetailOpened
|
||||
});
|
||||
};
|
||||
|
||||
this.on-key-down = (e) => {
|
||||
should-be-cancel = true
|
||||
switch
|
||||
| e.which == 38 or e.which == 74 or (e.which == 9 and e.shift-key) => // ↑, j or Shift+Tab
|
||||
focus this.root, (e) -> e.previousElementSibling
|
||||
| e.which == 40 or e.which == 75 or e.which == 9 => // ↓, k or Tab
|
||||
focus this.root, (e) -> e.nextElementSibling
|
||||
| e.which == 81 or e.which == 69 => // q or e
|
||||
@repost!
|
||||
| e.which == 70 or e.which == 76 => // f or l
|
||||
@like!
|
||||
| e.which == 82 => // r
|
||||
@reply!
|
||||
| _ =>
|
||||
should-be-cancel = false
|
||||
this.onKeyDown = e => {
|
||||
let shouldBeCancel = true;
|
||||
|
||||
if should-be-cancel
|
||||
e.preventDefault();
|
||||
switch (true) {
|
||||
case e.which == 38: // [↑]
|
||||
case e.which == 74: // [j]
|
||||
case e.which == 9 && e.shiftKey: // [Shift] + [Tab]
|
||||
focus(this.root, e => e.previousElementSibling);
|
||||
break;
|
||||
|
||||
function focus(el, fn)
|
||||
target = fn el
|
||||
if target?
|
||||
if target.has-attribute 'tabindex'
|
||||
case e.which == 40: // [↓]
|
||||
case e.which == 75: // [k]
|
||||
case e.which == 9: // [Tab]
|
||||
focus(this.root, e => e.nextElementSibling);
|
||||
break;
|
||||
|
||||
case e.which == 81: // [q]
|
||||
case e.which == 69: // [e]
|
||||
this.repost();
|
||||
break;
|
||||
|
||||
case e.which == 70: // [f]
|
||||
case e.which == 76: // [l]
|
||||
this.like();
|
||||
break;
|
||||
|
||||
case e.which == 82: // [r]
|
||||
this.reply();
|
||||
break;
|
||||
|
||||
default:
|
||||
shouldBeCancel = false;
|
||||
}
|
||||
|
||||
if (shouldBeCancel) e.preventDefault();
|
||||
};
|
||||
|
||||
function focus(el, fn) {
|
||||
const target = fn(el);
|
||||
if (target) {
|
||||
if (target.hasAttribute('tabindex')) {
|
||||
target.focus();
|
||||
else
|
||||
focus target, fn
|
||||
} else {
|
||||
focus(target, fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</mk-timeline-post>
|
||||
|
|
|
@ -501,7 +501,7 @@
|
|||
this.ondragover = (e) => {
|
||||
e.dataTransfer.dropEffect = 'none'
|
||||
|
||||
this.on-keydown = (e) => {
|
||||
this.onKeydown = (e) => {
|
||||
if e.which == 27 // Esc
|
||||
if @can-close
|
||||
e.preventDefault();
|
||||
|
|
|
@ -233,7 +233,7 @@
|
|||
description: description
|
||||
callback_url: cb
|
||||
permission: permission.join ','
|
||||
.then =>
|
||||
}).then(() => {
|
||||
location.href = '/apps'
|
||||
.catch =>
|
||||
alert 'アプリの作成に失敗しました。再度お試しください。'
|
||||
|
|
|
@ -192,9 +192,9 @@
|
|||
name = window.prompt '名前を変更' this.file.name
|
||||
if name? and name != '' and name != this.file.name
|
||||
this.api('drive/files/update', {
|
||||
file_id: this.file.id
|
||||
file_id: this.file.id,
|
||||
name: name
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.parent.cf this.file, true
|
||||
|
||||
</script>
|
||||
|
|
|
@ -84,21 +84,21 @@
|
|||
if this.user.is_following
|
||||
this.api('following/delete', {
|
||||
user_id: this.user.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.user.is_following = false
|
||||
.catch (err) ->
|
||||
console.error err
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.wait = false
|
||||
this.update();
|
||||
else
|
||||
this.api('following/create', {
|
||||
user_id: this.user.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.user.is_following = true
|
||||
.catch (err) ->
|
||||
console.error err
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.wait = false
|
||||
this.update();
|
||||
</script>
|
||||
|
|
|
@ -406,13 +406,13 @@
|
|||
if this.p.is_liked
|
||||
this.api('posts/likes/delete', {
|
||||
post_id: this.p.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.p.is_liked = false
|
||||
this.update();
|
||||
else
|
||||
this.api('posts/likes/create', {
|
||||
post_id: this.p.id
|
||||
.then =>
|
||||
}).then(() => {
|
||||
this.p.is_liked = true
|
||||
this.update();
|
||||
|
||||
|
|
|
@ -9,24 +9,24 @@
|
|||
<script>
|
||||
this.mixin('api');
|
||||
|
||||
this.max = 30
|
||||
this.offset = 0
|
||||
this.max = 30;
|
||||
this.offset = 0;
|
||||
|
||||
this.query = this.opts.query
|
||||
this.with-media = this.opts.with-media
|
||||
this.query = this.opts.query;
|
||||
this.withMedia = this.opts.withMedia;
|
||||
|
||||
this.init = new Promise (res, rej) =>
|
||||
this.api('posts/search', {
|
||||
query: @query
|
||||
}).then((posts) => {
|
||||
query: this.query
|
||||
}).then(posts => {
|
||||
res posts
|
||||
this.trigger('loaded');
|
||||
|
||||
this.more = () => {
|
||||
@offset += @max
|
||||
this.offset += this.max;
|
||||
this.api('posts/search', {
|
||||
query: @query
|
||||
max: @max
|
||||
offset: @offset
|
||||
query: this.query
|
||||
max: this.max
|
||||
offset: this.offset
|
||||
</script>
|
||||
</mk-search-posts>
|
||||
|
|
|
@ -11,21 +11,21 @@
|
|||
<script>
|
||||
this.mixin('api');
|
||||
|
||||
this.user = this.opts.user
|
||||
this.with-media = this.opts.with-media
|
||||
this.user = this.opts.user;
|
||||
this.withMedia = this.opts.withMedia;
|
||||
|
||||
this.init = new Promise (res, rej) =>
|
||||
this.api('users/posts', {
|
||||
user_id: this.user.id
|
||||
with_media: @with-media
|
||||
}).then((posts) => {
|
||||
with_media: @withMedia
|
||||
}).then(posts => {
|
||||
res posts
|
||||
this.trigger('loaded');
|
||||
|
||||
this.more = () => {
|
||||
this.api('users/posts', {
|
||||
user_id: this.user.id
|
||||
with_media: @with-media
|
||||
with_media: this.withMedia
|
||||
max_id: this.refs.timeline.tail!.id
|
||||
</script>
|
||||
</mk-user-timeline>
|
||||
|
|
Loading…
Reference in a new issue