mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
Fix profile dialog
This commit is contained in:
@@ -9,6 +9,7 @@ import { request, websocket } from "../websocket";
|
|||||||
import type { FetchDMResponse, SendDMRequest, WebSocketMessage, User, DmEnvelope } from "../core/types";
|
import type { FetchDMResponse, SendDMRequest, WebSocketMessage, User, DmEnvelope } from "../core/types";
|
||||||
import type { Tabs } from "mdui/components/tabs";
|
import type { Tabs } from "mdui/components/tabs";
|
||||||
import { b64, ub64 } from "../utils/utils";
|
import { b64, ub64 } from "../utils/utils";
|
||||||
|
import defaultAvatar from "../resources/images/default-avatar.png";
|
||||||
|
|
||||||
export async function sendDm(recipientId: number, recipientPublicKeyB64: string, plaintext: string): Promise<void> {
|
export async function sendDm(recipientId: number, recipientPublicKeyB64: string, plaintext: string): Promise<void> {
|
||||||
const keys = getCurrentKeys();
|
const keys = getCurrentKeys();
|
||||||
@@ -101,7 +102,7 @@ async function loadUsers() {
|
|||||||
|
|
||||||
// Add avatar
|
// Add avatar
|
||||||
const avatar = document.createElement("img");
|
const avatar = document.createElement("img");
|
||||||
avatar.src = u.profile_picture || "./src/resources/images/default-avatar.png";
|
avatar.src = u.profile_picture || defaultAvatar;
|
||||||
avatar.alt = u.username;
|
avatar.alt = u.username;
|
||||||
avatar.slot = "icon";
|
avatar.slot = "icon";
|
||||||
avatar.style.width = "40px";
|
avatar.style.width = "40px";
|
||||||
@@ -111,7 +112,7 @@ async function loadUsers() {
|
|||||||
|
|
||||||
// Handle avatar load error
|
// Handle avatar load error
|
||||||
avatar.addEventListener("error", () => {
|
avatar.addEventListener("error", () => {
|
||||||
avatar.src = "./src/resources/images/default-avatar.png";
|
avatar.src = defaultAvatar;
|
||||||
});
|
});
|
||||||
|
|
||||||
item.appendChild(avatar);
|
item.appendChild(avatar);
|
||||||
|
|||||||
Vendored
+8
@@ -224,3 +224,11 @@ export interface WebSocketCredentials {
|
|||||||
scheme: string;
|
scheme: string;
|
||||||
credentials: string;
|
credentials: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------
|
||||||
|
// React types
|
||||||
|
// -----------
|
||||||
|
export interface DialogProps {
|
||||||
|
isOpen: boolean;
|
||||||
|
onOpenChange: (value: boolean) => void;
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ import { PRODUCT_NAME } from "../../../core/config";
|
|||||||
import { useDialog } from "../../contexts/DialogContext";
|
import { useDialog } from "../../contexts/DialogContext";
|
||||||
import { useChat } from "../../hooks/useChat";
|
import { useChat } from "../../hooks/useChat";
|
||||||
import defaultAvatar from "../../../resources/images/default-avatar.png";
|
import defaultAvatar from "../../../resources/images/default-avatar.png";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { ProfileDialog } from "../profile/ProfileDialog";
|
||||||
|
|
||||||
function BottomAppBar() {
|
function BottomAppBar() {
|
||||||
const { openSettings } = useDialog();
|
const { openSettings } = useDialog();
|
||||||
@@ -70,20 +72,17 @@ function ChatTabs() {
|
|||||||
|
|
||||||
|
|
||||||
function ChatHeader() {
|
function ChatHeader() {
|
||||||
const { openProfile } = useDialog();
|
const [isProfileOpen, setProfileOpen] = useState(false);
|
||||||
|
|
||||||
const handleProfileClick = () => {
|
|
||||||
openProfile();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="chat-header-left">
|
<header className="chat-header-left">
|
||||||
<div className="product-name">{PRODUCT_NAME}</div>
|
<div className="product-name">{PRODUCT_NAME}</div>
|
||||||
<div className="profile">
|
<div className="profile">
|
||||||
<a href="#" id="profile-open" onClick={handleProfileClick}>
|
<a href="#" id="profile-open" onClick={() => setProfileOpen(true)}>
|
||||||
<img src={defaultAvatar} alt="" id="preview1" />
|
<img src={defaultAvatar} alt="" id="preview1" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
<ProfileDialog isOpen={isProfileOpen} onOpenChange={setProfileOpen} />
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ export function UserProfileDialog() {
|
|||||||
<mdui-dialog id="user-profile-dialog" close-on-overlay-click close-on-esc>
|
<mdui-dialog id="user-profile-dialog" close-on-overlay-click close-on-esc>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="profile-picture-section">
|
<div className="profile-picture-section">
|
||||||
<img className="profile-picture" src="" alt="Profile Picture" />
|
<img className="profile-picture" alt="Profile Picture" />
|
||||||
</div>
|
</div>
|
||||||
<div className="profile-info">
|
<div className="profile-info">
|
||||||
<div className="username-section">
|
<div className="username-section">
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import { useState } from "react";
|
import { useState, type FormEvent } from "react";
|
||||||
import { useDialog } from "../../contexts/DialogContext";
|
|
||||||
import defaultAvatar from "../../../resources/images/default-avatar.png";
|
import defaultAvatar from "../../../resources/images/default-avatar.png";
|
||||||
|
import type { TextField } from "mdui/components/text-field";
|
||||||
|
import type { DialogProps } from "../../../core/types";
|
||||||
|
|
||||||
export function ProfileDialog() {
|
export function ProfileDialog({ isOpen, onOpenChange }: DialogProps) {
|
||||||
const [username, setUsername] = useState("user123");
|
const [username, setUsername] = useState("user123");
|
||||||
const [description, setDescription] = useState("");
|
const [description, setDescription] = useState("");
|
||||||
const { isProfileOpen, closeProfile } = useDialog();
|
|
||||||
|
|
||||||
const handleSubmit = (e: React.FormEvent) => {
|
const handleSubmit = (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// TODO: Implement profile update logic
|
// TODO: Implement profile update logic
|
||||||
console.log("Profile update:", { username, description });
|
console.log("Profile update:", { username, description });
|
||||||
closeProfile();
|
onOpenChange(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<mdui-dialog id="profile-dialog" close-on-overlay-click close-on-esc open={isProfileOpen}>
|
<mdui-dialog id="profile-dialog" close-on-overlay-click close-on-esc open={isOpen}>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="header-top">
|
<div className="header-top">
|
||||||
<div className="profile-picture-container">
|
<div className="profile-picture-container">
|
||||||
@@ -28,7 +28,7 @@ export function ProfileDialog() {
|
|||||||
label="Имя пользователя"
|
label="Имя пользователя"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={username}
|
value={username}
|
||||||
onChange={(e: any) => setUsername(e.target.value)}
|
onChange={(e: FormEvent<HTMLElement & TextField>) => setUsername((e.target as TextField).value)}
|
||||||
autocomplete="username">
|
autocomplete="username">
|
||||||
</mdui-text-field>
|
</mdui-text-field>
|
||||||
</div>
|
</div>
|
||||||
@@ -39,13 +39,13 @@ export function ProfileDialog() {
|
|||||||
label="О себе"
|
label="О себе"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={description}
|
value={description}
|
||||||
onChange={(e: any) => setDescription(e.target.value)}
|
onChange={(e: FormEvent<HTMLElement & TextField>) => setDescription((e.target as TextField).value)}
|
||||||
placeholder="Расскажите о себе..."
|
placeholder="Расскажите о себе..."
|
||||||
autocomplete="none">
|
autocomplete="none">
|
||||||
</mdui-text-field>
|
</mdui-text-field>
|
||||||
<div className="dialog-actions">
|
<div className="dialog-actions">
|
||||||
<mdui-button type="submit" id="profile-submit">Сохранить изменения</mdui-button>
|
<mdui-button type="submit" id="profile-submit">Сохранить изменения</mdui-button>
|
||||||
<mdui-button id="profile-dialog-close" variant="outlined" onClick={closeProfile}>Закрыть</mdui-button>
|
<mdui-button id="profile-dialog-close" variant="outlined" onClick={() => onOpenChange(false)}>Закрыть</mdui-button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ export default function ChatScreen() {
|
|||||||
<>
|
<>
|
||||||
<ChatInterface />
|
<ChatInterface />
|
||||||
|
|
||||||
<ProfileDialog />
|
|
||||||
<CropperDialog />
|
<CropperDialog />
|
||||||
<SettingsDialog />
|
<SettingsDialog />
|
||||||
<MessageContextMenu />
|
<MessageContextMenu />
|
||||||
|
|||||||
Reference in New Issue
Block a user