Skip to content

Commit

Permalink
msg convo actions
Browse files Browse the repository at this point in the history
  • Loading branch information
ornicar committed Jan 26, 2020
1 parent 26bbf71 commit 25e869f
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 106 deletions.
4 changes: 4 additions & 0 deletions public/logo/lichess-thick3.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 16 additions & 2 deletions ui/msg/css/_convo.scss
Expand Up @@ -5,11 +5,11 @@
@extend %flex-column;
flex: 1 1 100%;
&__head {
@extend %flex-center;
@extend %flex-between;
flex: 0 0 $msg-top-height;
background: $c-bg-zebra2;
border-bottom: $border;
padding: 0 1vw;
padding: 0 1.5em 0 1vw;
.user-link {
@extend %flex-center-nowrap;
flex: 0 0 auto;
Expand All @@ -23,6 +23,15 @@
font-size: 1.5em;
}
}
&__actions {
@extend %flex-center;
}
}
&__action.button {
color: $c-font;
&.bad:hover {
color: $c-bad;
}
}
&__reply {
@extend %flex-center-nowrap;
Expand All @@ -37,6 +46,11 @@
background: $c-bg-box;
resize: none;
}
&__block {
flex: 1 1 auto;
text-align: center;
margin: .6em;
}
}
}
}
10 changes: 10 additions & 0 deletions ui/msg/src/ctrl.ts
Expand Up @@ -55,4 +55,14 @@ export default class MsgCtrl {
this.redraw();
}
}

block = () => {
const userId = this.data.convo?.thread.contact.id;
if (userId) network.block(userId).then(() => this.openConvo(userId));
}

unblock = () => {
const userId = this.data.convo?.thread.contact.id;
if (userId) network.unblock(userId).then(() => this.openConvo(userId));
}
}
14 changes: 14 additions & 0 deletions ui/msg/src/network.ts
Expand Up @@ -36,6 +36,20 @@ export function search(q: string) {
});
}

export function block(u: string) {
return $.ajax({
url: `/rel/block/${u}`,
method: 'post'
});
}

export function unblock(u: string) {
return $.ajax({
url: `/rel/unblock/${u}`,
method: 'post'
});
}

export function post(dest: string, text: string) {
window.lichess.pubsub.emit('socket.send', 'msgSend', { dest, text });
}
Expand Down
52 changes: 52 additions & 0 deletions ui/msg/src/view/actions.ts
@@ -0,0 +1,52 @@
import { h } from 'snabbdom'
import { VNode } from 'snabbdom/vnode'
import { Convo } from '../interfaces'
import { bind } from './util';
import MsgCtrl from '../ctrl';

export default function renderActions(ctrl: MsgCtrl, convo: Convo): VNode[] {
const user = convo.thread.contact, nodes = [];
const cls = 'msg-app__convo__action.button.button-empty';
nodes.push(
h(`a.${cls}`, {
key: 'play',
attrs: {
'data-icon': 'U',
href: `/?user=${user.name}#friend`,
title: ctrl.trans.noarg('challengeToPlay')
}
})
);
if (convo.relations.out === false) nodes.push(
h(`button.${cls}.unbad.text.hover-text`, {
key: 'unblock',
attrs: {
'data-icon': 'k',
title: ctrl.trans.noarg('blocked'),
'data-hover-text': ctrl.trans.noarg('unblock')
},
hook: bind('click', ctrl.unblock)
})
);
else nodes.push(
h(`button.${cls}.bad`, {
key: 'block',
attrs: {
'data-icon': 'k',
title: ctrl.trans.noarg('block')
},
hook: bind('click', ctrl.block)
})
);
nodes.push(
h(`button.${cls}.bad.confirm`, {
key: 'report',
attrs: {
'data-icon': '!',
href: '/report/flag',
title: ctrl.trans.noarg('report')
}
})
);
return nodes;
}
111 changes: 7 additions & 104 deletions ui/msg/src/view/convo.ts
Expand Up @@ -3,7 +3,8 @@ import { VNode } from 'snabbdom/vnode'
import { Convo } from '../interfaces'
import { userName } from './util';
import renderMsgs from './msgs';
import throttle from 'common/throttle';
import renderActions from './actions';
import renderTextarea from './textarea';
import MsgCtrl from '../ctrl';

export default function renderConvo(ctrl: MsgCtrl, convo: Convo): VNode {
Expand All @@ -26,109 +27,11 @@ export default function renderConvo(ctrl: MsgCtrl, convo: Convo): VNode {
]),
renderMsgs(ctrl, convo.msgs),
h('div.msg-app__convo__reply', [
h('textarea.msg-app__convo__reply__text', {
attrs: {
rows: 1,
autofocus: 1
},
hook: {
insert(vnode) {
setupTextarea(vnode.elm as HTMLTextAreaElement, user.id, ctrl.post);
}
}
})
convo.relations.out === false || convo.relations.in === false ?
h('div.msg-app__convo__reply__block.text', {
attrs: { 'data-icon': 'k' }
}, 'This conversation is blocked.') :
renderTextarea(ctrl, user)
])
]);
}

function renderActions(ctrl: MsgCtrl, convo: Convo): VNode[] {
const user = convo.thread.contact, nodes = [];
if (convo.relations.out) nodes.push(
h('button.msg-app__convo__action.text.hover-text', {
attrs: {
'data-icon': 'h',
href: `/rel/unfollow/${user.id}`,
title: ctrl.trans.noarg('following'),
'data-hover-text': ctrl.trans.noarg('unfollow')
}
})
);
else if (convo.relations.out === false) nodes.push(
h('button.msg-app__convo__action.text.hover-text', {
attrs: {
'data-icon': 'k',
href: `/rel/unblock/${user.id}`,
title: ctrl.trans.noarg('blocked'),
'data-hover-text': ctrl.trans.noarg('unblock')
}
})
);
else {
nodes.push(
h('a.msg-app__convo__action', {
attrs: {
'data-icon': 'h',
href: `/rel/follow/${user.id}`,
title: ctrl.trans.noarg('follow')
}
})
);
nodes.push(
h('a.msg-app__convo__action', {
attrs: {
'data-icon': 'k',
href: `/rel/block/${user.id}`,
title: ctrl.trans.noarg('block')
}
})
);
}
nodes.push(
h('a.msg-app__convo__action', {
attrs: {
'data-icon': 'i',
href: '/report/flag',
title: ctrl.trans.noarg('report')
}
})
);
return nodes;
}

function setupTextarea(area: HTMLTextAreaElement, contact: string, post: (text: string) => void) {

// save the textarea content until sent
const storage = window.lichess.storage.make(`msg:area:${contact}`);

// hack to automatically resize the textarea based on content
area.value = '';
let baseScrollHeight = area.scrollHeight;
area.addEventListener('input', throttle(500, () =>
setTimeout(() => {
const text = area.value.trim();
area.rows = 1;
// the resize magic
if (text) area.rows = Math.min(10, 1 + Math.ceil((area.scrollHeight - baseScrollHeight) / 19));
// and save content
storage.set(text);
})
));

// restore previously saved content
area.value = storage.get() || '';
if (area.value) area.dispatchEvent(new Event('input'));

// send the content on <enter.
area.addEventListener('keypress', (e: KeyboardEvent) => {
if ((e.which == 10 || e.which == 13) && !e.shiftKey) {
setTimeout(() => {
const txt = area.value.trim();
if (txt) post(txt);
area.value = '';
area.dispatchEvent(new Event('input')); // resize the textarea
storage.remove();
});
}
});
area.focus();
}
57 changes: 57 additions & 0 deletions ui/msg/src/view/textarea.ts
@@ -0,0 +1,57 @@
import { h } from 'snabbdom'
import { VNode } from 'snabbdom/vnode'
import { User } from '../interfaces'
import MsgCtrl from '../ctrl';
import throttle from 'common/throttle';

export default function renderTextarea(ctrl: MsgCtrl, user: User): VNode {
return h('textarea.msg-app__convo__reply__text', {
attrs: {
rows: 1,
autofocus: 1
},
hook: {
insert(vnode) {
setupTextarea(vnode.elm as HTMLTextAreaElement, user.id, ctrl.post);
}
}
});
}

function setupTextarea(area: HTMLTextAreaElement, contact: string, post: (text: string) => void) {

// save the textarea content until sent
const storage = window.lichess.storage.make(`msg:area:${contact}`);

// hack to automatically resize the textarea based on content
area.value = '';
let baseScrollHeight = area.scrollHeight;
area.addEventListener('input', throttle(500, () =>
setTimeout(() => {
const text = area.value.trim();
area.rows = 1;
// the resize magic
if (text) area.rows = Math.min(10, 1 + Math.ceil((area.scrollHeight - baseScrollHeight) / 19));
// and save content
storage.set(text);
})
));

// restore previously saved content
area.value = storage.get() || '';
if (area.value) area.dispatchEvent(new Event('input'));

// send the content on <enter.
area.addEventListener('keypress', (e: KeyboardEvent) => {
if ((e.which == 10 || e.which == 13) && !e.shiftKey) {
setTimeout(() => {
const txt = area.value.trim();
if (txt) post(txt);
area.value = '';
area.dispatchEvent(new Event('input')); // resize the textarea
storage.remove();
});
}
});
area.focus();
}

0 comments on commit 25e869f

Please sign in to comment.