mirror of
https://github.com/RetroShare/RSNewWebUI.git
synced 2026-09-12 19:50:04 +05:00
Added invite button for rooms
improve layout net settings Added missed config settings
This commit is contained in:
parent
9cb3b9bb4c
commit
e06efd3b0d
@ -708,6 +708,9 @@ const ChatHubState = {
|
||||
ownGxsIdentities: [],
|
||||
createRoomError: '',
|
||||
userSortMethod: 'name',
|
||||
showInviteModal: false,
|
||||
friendsList: [],
|
||||
selectedFriendsToInvite: new Set(),
|
||||
};
|
||||
|
||||
// ========================= Emoji Data =========================
|
||||
@ -926,6 +929,33 @@ const PublicLobbies = {
|
||||
|
||||
// ************************* Chat Hub Sub-Components ****************************
|
||||
|
||||
function loadFriendsForInvite() {
|
||||
ChatHubState.friendsList = [];
|
||||
rs.rsJsonApiRequest('/rsPeers/getFriendList', {}, (data) => {
|
||||
if (data && data.sslIds) {
|
||||
data.sslIds.forEach((sslId) => {
|
||||
rs.rsJsonApiRequest('/rsPeers/getPeerDetails', { sslId }, (detData) => {
|
||||
if (detData && detData.det) {
|
||||
rs.rsJsonApiRequest('/rsPeers/isOnline', { sslId }, (onlineData) => {
|
||||
ChatHubState.friendsList.push({
|
||||
id: sslId,
|
||||
name: detData.det.name,
|
||||
online: onlineData ? onlineData.retval : false
|
||||
});
|
||||
// Sort online friends first, then alphabetical name
|
||||
ChatHubState.friendsList.sort((a, b) => {
|
||||
if (a.online !== b.online) return a.online ? -1 : 1;
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const ChatRoomHeader = () => {
|
||||
return {
|
||||
view: (vnode) => {
|
||||
@ -975,21 +1005,35 @@ const ChatRoomHeader = () => {
|
||||
},
|
||||
[m('i.fas.fa-sign-out-alt'), ' Leave Chat']
|
||||
)
|
||||
: m(
|
||||
'button.red',
|
||||
{
|
||||
title: 'Leave Room',
|
||||
onclick: () => {
|
||||
ChatLobbyModel.unsubscribeChatLobby(lobbyHexId, () => {
|
||||
ChatHubState.selectedRoom = null;
|
||||
ChatHubState.selectedRoomId = null;
|
||||
ChatHubState.selectedRoomType = null;
|
||||
m.route.set('/chat');
|
||||
});
|
||||
: [
|
||||
m(
|
||||
'button',
|
||||
{
|
||||
title: 'Invite friends to this room',
|
||||
style: 'margin-right: 0.75rem;',
|
||||
onclick: () => {
|
||||
ChatHubState.showInviteModal = true;
|
||||
loadFriendsForInvite();
|
||||
}
|
||||
},
|
||||
},
|
||||
[m('i.fas.fa-sign-out-alt'), ' Leave']
|
||||
),
|
||||
[m('i.fas.fa-user-plus'), ' Invite']
|
||||
),
|
||||
m(
|
||||
'button.red',
|
||||
{
|
||||
title: 'Leave Room',
|
||||
onclick: () => {
|
||||
ChatLobbyModel.unsubscribeChatLobby(lobbyHexId, () => {
|
||||
ChatHubState.selectedRoom = null;
|
||||
ChatHubState.selectedRoomId = null;
|
||||
ChatHubState.selectedRoomType = null;
|
||||
m.route.set('/chat');
|
||||
});
|
||||
},
|
||||
},
|
||||
[m('i.fas.fa-sign-out-alt'), ' Leave']
|
||||
)
|
||||
],
|
||||
]),
|
||||
]);
|
||||
},
|
||||
@ -2002,7 +2046,7 @@ const Layout = {
|
||||
ChatHubState.createRoomError && m('p.error-text', { style: 'color: #ef4444; font-size: 0.85rem; margin: 0.5rem 0 0 0;' }, ChatHubState.createRoomError),
|
||||
|
||||
m('.modal-buttons', { style: 'display: flex; justify-content: flex-end; gap: 0.75rem; margin-top: 1rem;' }, [
|
||||
m('button.btn.blue', {
|
||||
m('button', {
|
||||
disabled: !ChatHubState.newRoomName.trim() || !ChatHubState.newRoomIdentity,
|
||||
onclick: () => {
|
||||
const name = ChatHubState.newRoomName.trim();
|
||||
@ -2037,7 +2081,7 @@ const Layout = {
|
||||
});
|
||||
}
|
||||
}, 'Create'),
|
||||
m('button.btn.red', {
|
||||
m('button.red', {
|
||||
onclick: () => {
|
||||
ChatHubState.showCreateRoomModal = false;
|
||||
ChatHubState.newRoomName = '';
|
||||
@ -2049,6 +2093,74 @@ const Layout = {
|
||||
])
|
||||
])
|
||||
]),
|
||||
ChatHubState.showInviteModal && m('.attach-modal-overlay', [
|
||||
m('.attach-modal', { style: 'max-width: 450px;' }, [
|
||||
m('h4', 'Invite Friends to ' + (ChatHubState.selectedRoom ? ChatHubState.selectedRoom.lobby_name : '')),
|
||||
m('.friends-invite-list', { style: 'max-height: 250px; overflow-y: auto; margin-top: 1rem; border: 1px solid #e2e8f0; border-radius: 0.375rem; padding: 0.5rem;' }, [
|
||||
ChatHubState.friendsList.length === 0
|
||||
? m('p', { style: 'text-align: center; color: #64748b; font-style: italic; margin: 1rem 0;' }, 'No friends available')
|
||||
: ChatHubState.friendsList.map((friend) => {
|
||||
const isChecked = ChatHubState.selectedFriendsToInvite.has(friend.id);
|
||||
return m('.friend-invite-item', {
|
||||
style: 'display: flex; align-items: center; justify-content: space-between; padding: 0.5rem; border-bottom: 1px solid #f1f5f9; cursor: pointer;',
|
||||
onclick: () => {
|
||||
if (isChecked) {
|
||||
ChatHubState.selectedFriendsToInvite.delete(friend.id);
|
||||
} else {
|
||||
ChatHubState.selectedFriendsToInvite.add(friend.id);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
m('div', { style: 'display: flex; align-items: center; gap: 0.5rem;' }, [
|
||||
m('.status-bullet', { style: { backgroundColor: friend.online ? '#22c55e' : '#94a3b8', width: '8px', height: '8px', borderRadius: '50%', display: 'inline-block' } }),
|
||||
m('span', { style: 'font-weight: 500;' }, friend.name)
|
||||
]),
|
||||
m('input[type=checkbox]', {
|
||||
checked: isChecked,
|
||||
onclick: (e) => {
|
||||
e.stopPropagation();
|
||||
if (e.target.checked) {
|
||||
ChatHubState.selectedFriendsToInvite.add(friend.id);
|
||||
} else {
|
||||
ChatHubState.selectedFriendsToInvite.delete(friend.id);
|
||||
}
|
||||
}
|
||||
})
|
||||
]);
|
||||
})
|
||||
]),
|
||||
m('.modal-buttons', { style: 'display: flex; justify-content: flex-end; gap: 0.75rem; margin-top: 1.5rem;' }, [
|
||||
m('button', {
|
||||
disabled: ChatHubState.selectedFriendsToInvite.size === 0,
|
||||
onclick: () => {
|
||||
const lobbyHexId = rs.idToHex(ChatHubState.selectedRoom.lobby_id);
|
||||
const invitePromises = [];
|
||||
ChatHubState.selectedFriendsToInvite.forEach((friendId) => {
|
||||
invitePromises.push(
|
||||
new Promise((resolve) => {
|
||||
rs.rsJsonApiRequest('/rsChats/invitePeerToLobby', {
|
||||
lobby_id: lobbyHexId,
|
||||
peer_id: friendId
|
||||
}, () => resolve());
|
||||
})
|
||||
);
|
||||
});
|
||||
Promise.all(invitePromises).then(() => {
|
||||
ChatHubState.showInviteModal = false;
|
||||
ChatHubState.selectedFriendsToInvite.clear();
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
}, 'Invite'),
|
||||
m('button.red', {
|
||||
onclick: () => {
|
||||
ChatHubState.showInviteModal = false;
|
||||
ChatHubState.selectedFriendsToInvite.clear();
|
||||
}
|
||||
}, 'Cancel')
|
||||
])
|
||||
])
|
||||
]),
|
||||
]),
|
||||
|
||||
m('.chat-hub-right-pane', [
|
||||
|
||||
@ -328,40 +328,44 @@ const SetSocksProxy = () => {
|
||||
});
|
||||
},
|
||||
view: () =>
|
||||
m('.proxy-server', [
|
||||
m('.proxy-server-container', [
|
||||
m(
|
||||
'p',
|
||||
'p.proxy-description',
|
||||
'Configure your TOR and I2P SOCKS proxy here. It will allow you to also connect to hidden nodes.'
|
||||
),
|
||||
Object.keys(socksProxyObj).map((proxyItem) => {
|
||||
return m(`.proxy-server__${proxyItem}`, [
|
||||
m('h6', `${proxyItem.toUpperCase()} Socks Proxy: `),
|
||||
m('input[type=text]', {
|
||||
value: socksProxyObj[proxyItem].addr,
|
||||
oninput: (e) => (socksProxyObj[proxyItem].addr = e.target.value),
|
||||
onchange: () => handleProxyChange(proxyItem),
|
||||
}),
|
||||
m('input[type=number]', {
|
||||
value: socksProxyObj[proxyItem].port,
|
||||
oninput: (e) => (socksProxyObj[proxyItem].port = parseInt(e.target.value)),
|
||||
onchange: () => handleProxyChange(proxyItem),
|
||||
}),
|
||||
socksProxyObj[proxyItem].outgoing !== undefined &&
|
||||
m('.proxy-outgoing', [
|
||||
m('.proxy-outgoing__status', {
|
||||
style: {
|
||||
backgroundColor: socksProxyObj[proxyItem].outgoing ? '#00dd44' : '#808080',
|
||||
},
|
||||
}),
|
||||
m(
|
||||
'p',
|
||||
`${proxyItem.toUpperCase()} outgoing ${
|
||||
socksProxyObj[proxyItem].outgoing ? 'on' : 'off'
|
||||
}`
|
||||
),
|
||||
]),
|
||||
]);
|
||||
}),
|
||||
m('.proxy-rows-container',
|
||||
Object.keys(socksProxyObj).map((proxyItem) => {
|
||||
const isTor = proxyItem === 'tor';
|
||||
const labelText = isTor ? 'TOR Socks Proxy:' : 'I2P Socks Proxy:';
|
||||
const outgoingText = isTor ? 'TOR outgoing' : 'I2P outgoing';
|
||||
const isOutgoing = socksProxyObj[proxyItem].outgoing;
|
||||
return m('.proxy-row', [
|
||||
m('label.proxy-label', labelText),
|
||||
m('input[type=text].proxy-addr-input', {
|
||||
value: socksProxyObj[proxyItem].addr,
|
||||
oninput: (e) => (socksProxyObj[proxyItem].addr = e.target.value),
|
||||
onchange: () => handleProxyChange(proxyItem),
|
||||
}),
|
||||
m('input[type=number].proxy-port-input', {
|
||||
value: socksProxyObj[proxyItem].port,
|
||||
oninput: (e) => (socksProxyObj[proxyItem].port = parseInt(e.target.value)),
|
||||
onchange: () => handleProxyChange(proxyItem),
|
||||
}),
|
||||
socksProxyObj[proxyItem].outgoing !== undefined &&
|
||||
m('.proxy-status-container', [
|
||||
m('.proxy-status-bullet', {
|
||||
style: {
|
||||
backgroundColor: isOutgoing ? '#22c55e' : '#808080',
|
||||
},
|
||||
}),
|
||||
m(
|
||||
'span.proxy-status-text',
|
||||
`${outgoingText} ${isOutgoing ? 'on' : 'off'}`
|
||||
),
|
||||
]),
|
||||
]);
|
||||
})
|
||||
),
|
||||
]),
|
||||
};
|
||||
};
|
||||
@ -397,7 +401,7 @@ const Component = () => {
|
||||
m(displayIPAddresses, { details }),
|
||||
]),
|
||||
m('.widget__heading', m('h3', 'Hidden Service Configuration')),
|
||||
m('.widget__body', [m('.grid-2col', [m(SetSocksProxy)])]),
|
||||
m('.widget__body', [m(SetSocksProxy)]),
|
||||
]),
|
||||
]),
|
||||
};
|
||||
|
||||
@ -5,6 +5,7 @@ const Reputation = () => {
|
||||
let addFriendIdAsContacts = undefined;
|
||||
let usePositiveDefault = undefined;
|
||||
let deleteBannedAfter = undefined;
|
||||
let rememberBannedAfter = undefined;
|
||||
let negativeThreshold = undefined;
|
||||
let positiveThreshold = undefined;
|
||||
|
||||
@ -25,6 +26,11 @@ const Reputation = () => {
|
||||
{},
|
||||
(data) => (deleteBannedAfter = data.retval)
|
||||
);
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/rememberBannedIdThreshold',
|
||||
{},
|
||||
(data) => (rememberBannedAfter = data.retval)
|
||||
);
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/thresholdForRemotelyPositiveReputation',
|
||||
{},
|
||||
@ -95,7 +101,7 @@ const Reputation = () => {
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
m('p', 'Delete banned identities after(in days, 0 means indefinitely):'),
|
||||
m('p', 'Delete banned identities after(0 means never):'),
|
||||
m('input[type=number]', {
|
||||
oninput: (e) => (deleteBannedAfter = parseInt(e.target.value)),
|
||||
value: deleteBannedAfter,
|
||||
@ -108,6 +114,19 @@ const Reputation = () => {
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
m('p', 'Reset reputation of banned identities after (0 means never):'),
|
||||
m('input[type=number]', {
|
||||
oninput: (e) => (rememberBannedAfter = parseInt(e.target.value)),
|
||||
value: rememberBannedAfter,
|
||||
onchange: () =>
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsreputations/setRememberBannedIdThreshold',
|
||||
{
|
||||
days: rememberBannedAfter,
|
||||
},
|
||||
() => {}
|
||||
),
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
|
||||
@ -1998,3 +1998,67 @@ table.mails th.sortable-th:hover {
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* Hidden Service Configuration layout overrides */
|
||||
.proxy-server-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.proxy-description {
|
||||
color: #334155;
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.proxy-rows-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.proxy-row {
|
||||
display: grid;
|
||||
grid-template-columns: 160px 220px 220px auto;
|
||||
gap: 0.75rem;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.proxy-label {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.proxy-addr-input {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.proxy-port-input {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.proxy-status-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.proxy-status-bullet {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
border: 1px solid #475569;
|
||||
}
|
||||
|
||||
.proxy-status-text {
|
||||
font-size: 0.95rem;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user