mirror of
https://github.com/vacp2p/de-mls.git
synced 2026-01-09 15:18:00 -05:00
* start to update ui * remove websocket ui * refactor code after ws removing * update frontend * Unable real consensus result * update proposal ui * add current pending proposal to ui section * Refactor UI and backend for ban request feature - Updated `build.rs` to ensure proper protobuf compilation. - Removed `tracing-subscriber` dependency from `Cargo.toml` and `Cargo.lock`. - Refactored `main.rs` in the desktop UI to improve state management and UI interactions for group chat. - Enhanced `Gateway` and `User` structs to support sending ban requests and processing related events. - Updated UI components to reflect changes in proposal handling and improve user experience during voting and group management. - Added tests for new functionality and improved error handling across modules. * Add mls_crypto integration and group member management features - Introduced `mls_crypto` as a dependency for wallet address normalization. - Enhanced the desktop UI to support group member management, including requesting user bans. - Implemented new commands and events in the `Gateway` and `User` structs for retrieving group members and processing ban requests. - Updated the `User` struct to include methods for fetching group members and validating wallet addresses. - Refactored various components to improve state management and UI interactions related to group chat and member actions. - Added error handling for invalid wallet addresses and improved overall user experience in group management features. * Replace Apache License with a new version and add MIT License; update README to reflect new licensing information and enhance user module documentation. Refactor user module to improve group management, consensus handling, and messaging features, including ban request processing and proposal management. * Update dependencies and refactor package names for consistency * update ci * update ci * - Added `mls_crypto` as a dependency for wallet address normalization. - Introduced a new CSS file for styling the desktop UI, improving overall aesthetics and user experience. - Enhanced the `User` and `Gateway` structs to support group member management, including ban requests and proposal handling. - Implemented new commands and events for retrieving group members and processing ban requests. - Refactored various components to improve state management and UI interactions related to group chat and member actions. - Updated the `Cargo.toml` and `Cargo.lock` files to reflect new dependencies and configurations. - Added new profiles for development builds targeting WebAssembly, server, and Android environments.
620 lines
11 KiB
CSS
620 lines
11 KiB
CSS
:root {
|
|
--bg: #0b0d10;
|
|
--card: #14161c;
|
|
--text: #e5e7ec;
|
|
--muted: #9094a2;
|
|
--primary: #00b2ff;
|
|
--primary-2: #007ad9;
|
|
--border: #1c1e25;
|
|
--good: #00f5a0;
|
|
--bad: #ff005c;
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html,
|
|
body,
|
|
#main {
|
|
height: 100%;
|
|
width: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, Noto Sans, Apple Color Emoji, Segoe UI Emoji;
|
|
}
|
|
|
|
.page {
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
h1 {
|
|
margin: 0 0 16px 0;
|
|
font-size: 22px;
|
|
}
|
|
|
|
.header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 8px 12px;
|
|
border-bottom: 1px solid var(--border);
|
|
background: rgba(255, 255, 255, 0.03);
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 5;
|
|
}
|
|
|
|
.header .brand {
|
|
font-weight: 700;
|
|
letter-spacing: .5px;
|
|
}
|
|
|
|
.header .user-hint {
|
|
color: var(--muted);
|
|
font-size: 12px;
|
|
padding: 4px 8px;
|
|
border: 1px dashed var(--border);
|
|
border-radius: 8px;
|
|
max-width: 420px;
|
|
}
|
|
|
|
.header .spacer {
|
|
flex: 1;
|
|
}
|
|
|
|
.header .label {
|
|
color: var(--muted);
|
|
}
|
|
|
|
.header .level {
|
|
padding: 6px 8px;
|
|
border-radius: 8px;
|
|
border: 1px solid var(--border);
|
|
background: var(--card);
|
|
color: var(--text);
|
|
outline: none;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.page.login {
|
|
max-width: 520px;
|
|
margin-top: 32px;
|
|
}
|
|
|
|
.form-row {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
margin: 12px 0;
|
|
}
|
|
|
|
input,
|
|
select {
|
|
padding: 10px 12px;
|
|
border-radius: 8px;
|
|
border: 1px solid var(--border);
|
|
background: var(--card);
|
|
color: var(--text);
|
|
outline: none;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.input-error {
|
|
color: var(--bad);
|
|
font-size: 12px;
|
|
}
|
|
|
|
button {
|
|
border: 1px solid var(--border);
|
|
background: var(--card);
|
|
color: var(--text);
|
|
padding: 10px 14px;
|
|
border-radius: 10px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
button.primary {
|
|
background: var(--primary);
|
|
border-color: var(--primary);
|
|
color: white;
|
|
}
|
|
|
|
button.primary:hover {
|
|
background: var(--primary-2);
|
|
}
|
|
|
|
button.secondary {
|
|
background: transparent;
|
|
}
|
|
|
|
button.ghost {
|
|
background: transparent;
|
|
border-color: var(--border);
|
|
color: var(--muted);
|
|
}
|
|
|
|
button.icon {
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
button.mini {
|
|
padding: 4px 8px;
|
|
border-radius: 8px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.alerts {
|
|
position: fixed;
|
|
top: 64px;
|
|
right: 24px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
z-index: 20;
|
|
}
|
|
|
|
.alert {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 10px;
|
|
min-width: 260px;
|
|
max-width: 420px;
|
|
padding: 12px 14px;
|
|
border-radius: 10px;
|
|
border: 1px solid var(--border);
|
|
background: var(--card);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
.alert.error {
|
|
border-color: rgba(255, 0, 92, 0.4);
|
|
background: rgba(255, 0, 92, 0.1);
|
|
color: var(--bad);
|
|
}
|
|
|
|
.alert .message {
|
|
flex: 1;
|
|
font-size: 13px;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.member-picker {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.member-picker .helper {
|
|
color: var(--muted);
|
|
font-size: 13px;
|
|
}
|
|
|
|
.member-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
max-height: 260px;
|
|
overflow-y: auto;
|
|
padding-right: 4px;
|
|
}
|
|
|
|
.member-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-start;
|
|
gap: 10px;
|
|
background: transparent;
|
|
box-shadow: none;
|
|
border: none;
|
|
width: 100%;
|
|
}
|
|
|
|
.member-item .member-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 10px;
|
|
width: 100%;
|
|
}
|
|
|
|
.member-item .member-id {
|
|
font-size: 12px;
|
|
font-weight: 400;
|
|
letter-spacing: 0.02em;
|
|
color: var(--text);
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
overflow-wrap: anywhere;
|
|
flex: 1;
|
|
}
|
|
|
|
.member-item .member-choose {
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.04em;
|
|
text-transform: none;
|
|
padding: 6px 12px;
|
|
border-radius: 999px;
|
|
border: none;
|
|
background: var(--primary);
|
|
color: white;
|
|
cursor: pointer;
|
|
box-shadow: 0 6px 18px rgba(0, 178, 255, 0.35);
|
|
}
|
|
|
|
.member-item .member-choose:hover {
|
|
background: var(--primary-2);
|
|
box-shadow: 0 6px 18px rgba(0, 122, 217, 0.45);
|
|
}
|
|
|
|
/* Home layout */
|
|
.page.home {
|
|
padding: 12px;
|
|
}
|
|
|
|
.layout {
|
|
display: grid;
|
|
grid-template-columns: 280px 1fr 500px;
|
|
gap: 12px;
|
|
}
|
|
|
|
.mono {
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
}
|
|
|
|
.ellipsis {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
|
|
.panel {
|
|
background: var(--card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
padding: 12px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.panel h2 {
|
|
margin: 0 0 6px 0;
|
|
font-size: 18px;
|
|
}
|
|
|
|
.hint {
|
|
color: var(--muted);
|
|
padding: 8px 0;
|
|
}
|
|
|
|
.panel.groups .group-list {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
/* Group list a bit wider rows to align with long names */
|
|
.group-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 10px 12px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.group-row .title {
|
|
font-weight: 600;
|
|
max-width: 220px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.panel.groups .footer {
|
|
margin-top: auto;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 8px;
|
|
}
|
|
|
|
.panel.groups .footer .primary {
|
|
flex: 1;
|
|
}
|
|
|
|
/* Chat */
|
|
.panel.chat .messages {
|
|
min-height: 360px;
|
|
height: 58vh;
|
|
overflow-y: auto;
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
padding: 12px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.panel.chat .chat-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.msg {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.msg.me {
|
|
align-items: flex-end;
|
|
}
|
|
|
|
.msg.me .body {
|
|
background: rgba(79, 140, 255, 0.15);
|
|
border: 1px solid rgba(79, 140, 255, 0.35);
|
|
padding: 8px 10px;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.msg.system {
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.msg.system .body {
|
|
font-style: italic;
|
|
color: var(--muted);
|
|
background: transparent;
|
|
border: none;
|
|
padding: 0;
|
|
}
|
|
|
|
.msg .from {
|
|
color: var(--muted);
|
|
font-size: 16px;
|
|
}
|
|
|
|
.msg .body {
|
|
color: var(--text);
|
|
background: rgba(255, 255, 255, 0.05);
|
|
border: 1px solid var(--border);
|
|
padding: 8px 10px;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.composer {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
|
|
.composer input {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.composer button {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
/* Consensus panel */
|
|
.panel.consensus .status {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.panel.consensus .status .good {
|
|
color: var(--good);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.panel.consensus .status .bad {
|
|
color: var(--bad);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.panel.consensus .proposal-item {
|
|
display: grid;
|
|
grid-template-columns: minmax(6rem, max-content) 1fr;
|
|
align-items: start;
|
|
gap: 8px;
|
|
padding: 6px 8px;
|
|
border-radius: 6px;
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
.panel.consensus .proposal-item .action {
|
|
color: var(--primary);
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.panel.consensus .proposal-item .value {
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
color: var(--text);
|
|
font-size: 12px;
|
|
overflow-wrap: anywhere;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.panel.consensus .proposal-item.proposal-id {
|
|
background: rgba(0, 178, 255, 0.08);
|
|
border-color: rgba(0, 178, 255, 0.45);
|
|
box-shadow: inset 0 0 0 1px rgba(0, 178, 255, 0.15);
|
|
}
|
|
|
|
.panel.consensus .proposal-item.proposal-id .action {
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
}
|
|
|
|
.panel.consensus .proposal-item.proposal-id .value {
|
|
font-weight: 700;
|
|
font-size: 13px;
|
|
letter-spacing: 0.03em;
|
|
}
|
|
|
|
/* Consensus sections */
|
|
.panel.consensus {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
}
|
|
|
|
.panel.consensus .status {
|
|
flex-shrink: 0;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.panel.consensus .consensus-section {
|
|
margin: 8px 0;
|
|
padding: 12px;
|
|
border-radius: 10px;
|
|
background: rgba(255, 255, 255, 0.02);
|
|
border: 1px solid var(--border);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.panel.consensus .consensus-section h3 {
|
|
margin: 0 0 12px 0;
|
|
font-size: 14px;
|
|
color: var(--primary);
|
|
border-bottom: 1px solid var(--border);
|
|
padding-bottom: 8px;
|
|
}
|
|
|
|
.panel.consensus .no-data {
|
|
color: var(--muted);
|
|
font-style: italic;
|
|
text-align: center;
|
|
padding: 20px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.panel.consensus .proposals-window {
|
|
overflow-y: auto;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.panel.consensus .vote-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
justify-content: flex-end;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
/* Consensus results window */
|
|
.panel.consensus .results-window {
|
|
overflow-y: auto;
|
|
border: 1px solid var(--border);
|
|
border-radius: 8px;
|
|
padding: 8px;
|
|
background: rgba(255, 255, 255, 0.02);
|
|
max-height: 200px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.panel.consensus .result-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 6px 8px;
|
|
border-radius: 6px;
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border: 1px solid var(--border);
|
|
font-size: 13px;
|
|
}
|
|
|
|
.panel.consensus .result-item .proposal-id {
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
color: var(--muted);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.panel.consensus .result-item .outcome {
|
|
font-weight: 600;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.panel.consensus .result-item .outcome.accepted {
|
|
color: var(--good);
|
|
background: rgba(23, 201, 100, 0.1);
|
|
}
|
|
|
|
.panel.consensus .result-item .outcome.rejected {
|
|
color: var(--bad);
|
|
background: rgba(243, 18, 96, 0.1);
|
|
}
|
|
|
|
.panel.consensus .result-item .outcome.unspecified {
|
|
color: var(--muted);
|
|
background: rgba(163, 167, 179, 0.1);
|
|
}
|
|
|
|
.panel.consensus .result-item .timestamp {
|
|
color: var(--muted);
|
|
font-size: 11px;
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
}
|
|
|
|
/* Modal */
|
|
.modal-backdrop {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(0, 0, 0, .45);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.modal {
|
|
width: 520px;
|
|
max-width: calc(100vw - 32px);
|
|
background: var(--card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 14px;
|
|
box-shadow: 0 0 6px var(--primary);
|
|
}
|
|
|
|
.modal-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 12px 14px;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.modal-body {
|
|
padding: 14px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
justify-content: flex-end;
|
|
margin-top: 6px;
|
|
}
|