various fixes

main
jerl 2024-06-19 22:57:57 -07:00
parent c87c193118
commit 3b288c9719
6 changed files with 93 additions and 70 deletions

View File

@ -69,8 +69,11 @@ window.getUser = async (id, name) => {
);
};
window.makeUser = (user, url, removable) => {
removable &&= window.currentThread.permissions.admin && !user.permissions?.admin;
window.makeUser = (user, url, context) => {
let removable = context === 'user' ? false :
window.currentThread?.permissions.admin && !user.permissions?.admin &&
(context === 'member' ? true : Array.from(document.getElementById('memberlist').children)
.find(p => p.children[0].user?.id == user.id));
let span = html.node`
<span class='user' onclick=${function(e) {
let member = document.getElementById('member');
@ -134,7 +137,7 @@ function instanceClicked(event) {
instance.emit?.('list_users', {}, msg =>
userlist.replaceChildren(...msg.users.map(user => {
let p = document.createElement('p');
p.append(window.makeUser(user, instance.url));
p.append(window.makeUser(user, instance.url, 'user'));
return p;
}))
);
@ -192,32 +195,34 @@ document.body.append(html.node`
<input id='profilepublic' type='checkbox' oninput=${saveProfile}>
<label for='profilepublic'>show profile in instance users</label>
</p>
<label class='heading'>authentication requests</label>
<label class='heading'>authentication requests:</label>
<div id='authrequests'></div>
</div>
<hr class='separator' color='#505050'>
<div id='home' class='column'>
<h3>vybe</h3>
<p id='instances'>instances:<button onclick=${e => {
let div = html.node`
<div>
<div class='instancetitle'>
<span></span>
<span onblur=${addInstance} onkeydown=${function(event) {
if (event.key === 'Enter') {
event.preventDefault();
addInstance.call(this);
}
}} class='title' contenteditable='true'>
</span>
</div>
</div>`;
document.getElementById('instancelist').append(div);
div.children[0].children[1].focus();
}}>add</button></p>
<div id='instancelist'>
<h3>vybe</h3>
<p id='instances'>instances:<button onclick=${() => {
let div = html.node`
<div>
<div class='instancetitle'>
<span></span>
<span onblur=${addInstance} onkeydown=${function(event) {
if (event.key === 'Enter') {
event.preventDefault();
addInstance.call(this);
}
}} class='title' contenteditable='true'>
</span>
</div>
</div>`;
document.getElementById('instancelist').append(div);
div.children[0].children[1].focus();
}}>add</button></p>
</div>
<div id='user' onclick=${() =>
<div class='content'><!-- empty flex div to push instancelist up -->
</div>
<div id='user' onclick=${e =>
document.getElementById('profile').classList.toggle('hidden')
}>${window.name}</div>
</div>

View File

@ -174,7 +174,8 @@
.user {
white-space: pre-wrap;
&:hover {
background-color: #444;
background-color: #333;
border-bottom: 1px #bbb solid;
}
}
#profile {

View File

@ -72,8 +72,7 @@ function loadMessages(callback) {
}
}
let div = html.node`<div class='message'>: ${message.content}</div>`;
div.prepend(user ? window.makeUser(user,
user.id.split?.('@')[1] || instance.url, true)
div.prepend(user ? window.makeUser(user, user.id.split?.('@')[1] || instance.url)
: html.node`<span>${message.user.id}</span>`);
messages.prepend(div);
}
@ -93,7 +92,7 @@ function loadMessages(callback) {
let scroll = messages.scrollTop + 10 >= messages.scrollHeight - messages.clientHeight;
let div = html.node`<div class='message'>: ${message.content}</div>`;
div.prepend(window.makeUser(message.user,
message.user.id.split?.('@')[1] || instance.url, true));
message.user.id.split?.('@')[1] || instance.url));
messages.append(div);
if (scroll)
messages.scroll(0, messages.scrollHeight - messages.clientHeight);

View File

@ -78,7 +78,7 @@ function loadStreams() {
let div = document.getElementById('stream');
div.innerHTML = '';
if (window.currentThread.permissions.post) {
if (window.currentThread?.permissions.post) {
// why doesn't html` work here? html.node` does
render(div, html.node`
<button id='streaming' onclick=${stream}>
@ -92,7 +92,10 @@ function loadStreams() {
thread: window.currentThread.id,
name: this.value
});
window.currentThread.streamname = this.value;
}}>`);
if (window.currentThread.streamname)
document.getElementById('streamname').value = window.currentThread.streamname;
}
div.insertAdjacentHTML('beforeend', `
<p>streams:</p>
@ -123,8 +126,11 @@ function loadStreams() {
console.log('play stream failed: ', msg.message);
});
}}>${instance.streaming[stream.id] ? '⏹' : '▶'}</button>
${stream.user}<span id='name'>${stream.name ? ` - ${stream.name}` : ''}</span>
<span id='name'>${stream.name ? ` - ${stream.name}` : ''}</span>
</p>`;
p.insertBefore(window.makeUser(stream.user,
stream.user.id.split?.('@')[1] || window.currentInstance.url),
p.children[1]);
p.id = 'stream' + stream.id;
document.getElementById('streams').append(p);
}
@ -167,8 +173,9 @@ function loadStreams() {
});
}
for (let stream of window.currentThread.streams)
addStream(stream);
if (window.currentThread)
for (let stream of window.currentThread.streams)
addStream(stream);
}
export default loadStreams;

View File

@ -39,26 +39,17 @@ function chooseThread() {
}
else
document.getElementById('thread').classList.remove('hidden');
if (thread.permissions.admin)
if (thread.permissions.admin) {
edit.classList.remove('hidden');
else
document.getElementById('membersadd').classList.remove('hidden');
} else {
edit.classList.add('hidden');
document.getElementById('membersadd').classList.add('hidden');
}
document.getElementById('threadname').textContent = thread.name;
this.classList.add('active');
window.currentThread = thread;
window.currentInstance = thread.instance;
let tab = url.searchParams.get('tab');
if (!['message', 'space', 'stream'].includes(tab))
tab = null;
if (tab || this.tab) {
if (tab)
this.tab = tab + 'tab';
switchTab(document.getElementById(this.tab));
if (this.tab === 'messagetab')
loadMessages();
else if (this.tab === 'spacetab')
loadSpace();
}
let div = this;
window.currentInstance.emit('get_thread', { thread: thread.id }, async msg => {
if (!msg.success) {
@ -71,13 +62,13 @@ function chooseThread() {
...await Promise.all(msg.thread.members.map(async member => {
let p = document.createElement('p');
if (member.name)
p.append(window.makeUser(member, window.currentInstance.url, true));
p.append(window.makeUser(member, window.currentInstance.url, 'member'));
else
try {
let user = await window.getUser(member.id);
user.id = member.id;
user.permissions = member.permissions;
p.append(window.makeUser(user, user.id.split?.('@')[1], true));
p.append(window.makeUser(user, user.id.split?.('@')[1], 'member'));
}
catch (e) {
console.log(`error getting user ${member.id}: ${e}`);
@ -87,9 +78,20 @@ function chooseThread() {
}))
);
loadStreams();
if (!div.tab)
let tab = url.searchParams.get('tab');
if (!['message', 'space', 'stream'].includes(tab))
tab = null;
if (tab || this.tab) {
if (tab)
this.tab = tab + 'tab';
switchTab(document.getElementById(this.tab));
if (this.tab === 'messagetab')
loadMessages();
else if (this.tab === 'spacetab')
loadSpace();
}
else // load first tab that has any content
await new Promise(resolve => {
// load first tab that has any content
loadMessages(messages => {
if (messages.length) {
switchTab(document.getElementById(div.tab = 'messagetab'));
@ -108,8 +110,13 @@ function chooseThread() {
});
});
});
url.searchParams.set('thread', thread.id);
url.searchParams.set('tab', div.tab.substring(0, div.tab.length - 3));
if (window.currentInstance === window.instancelist[0]) {
url.searchParams.set('thread', thread.id);
url.searchParams.set('tab', div.tab.substring(0, div.tab.length - 3));
} else {
url.searchParams.delete('thread');
url.searchParams.delete('tab');
}
window.history.pushState(null, '', url.toString());
});
}
@ -327,10 +334,8 @@ async function addMember() {
name.value = '';
document.getElementById('addmember').classList.add('hidden');
}
if (!name.value) {
close();
return;
}
if (!name.value)
return close();
let at = name.value.split('@');
let url = at[1] || window.currentInstance.url;
let user = await window.getUser('@' + url, at[0]);
@ -339,15 +344,11 @@ async function addMember() {
return;
}
error.innerText = '';
if (window.currentInstance.url !== url) {
if (window.currentInstance.url !== url)
user.id += '@' + url;
user.name += '@' + url;
}
for (let p of document.getElementById('memberlist').children)
if (p.children[0].user.id == user.id) {
close();
return;
}
if (p.children[0].user.id == user.id)
return close();
window.currentInstance.emit('add_member', {
id: String(user.id),
thread: window.currentThread.id
@ -359,7 +360,7 @@ async function addMember() {
}
close();
let p = document.createElement('p');
p.append(window.makeUser(user, url, true));
p.append(window.makeUser(user, url, 'member'));
document.getElementById('memberlist').append(p);
});
}
@ -404,7 +405,7 @@ async function loadThreads(instancediv, select) {
<p id='visibility'></p>
<div id='membershead'>
<strong>members</strong>
<button onclick=${e => {
<button id='membersadd' onclick=${e => {
document.getElementById('addmember').classList.remove('hidden');
document.getElementById('addmembername').focus();
}}>add</button>

View File

@ -26,8 +26,7 @@ async function stream(msg, respond, socket) {
socket.emit('stream', stream);
} else {
for (let member of (
await db.query(
'select user from member where member.thread = ?', msg.thread)
await db.query('select user from member where member.thread = ?', msg.thread)
).rows) {
member = vybe.users[member.user];
if (member)
@ -49,19 +48,30 @@ async function stream(msg, respond, socket) {
message: "stream doesn't belong to user"
});
if (msg.stop) {
stream.stop();
await stream.stop();
return respond({
success: true
});
}
stream = stream.stream;
stream.name = msg.name;
stream.user.displayname = msg.auth_user.displayname;
}
else {
stream = {
id: newstreamid++,
thread: msg.thread,
user: msg.auth_user.displayname,
user: {
id: msg.auth_user.id,
name: msg.auth_user.name,
displayname: msg.auth_user.displayname,
permissions: Object.fromEntries((await db.query(
`select permission, value from permission
where type = 'user' and thread = ? and user = ?`,
[msg.thread, msg.auth_user.id])).rows.map(p =>
[p.permission, ['admin', 'post', 'view'].includes(p.permission)
? p.value === 'true' : p.value]))
},
name: msg.name
};
thread.streams.push(stream);
@ -70,11 +80,11 @@ async function stream(msg, respond, socket) {
userid: msg.auth_user.id,
listeners: {},
socket: socket.id,
stop: () => {
stop: async () => {
stream.stopped = true;
thread.streams.splice(thread.streams.findIndex(s => s.id === stream.id), 1);
delete vybe.streams[stream.id];
send();
await send();
}
};
}