...
This commit is contained in:
parent
213c0a70f0
commit
a535e43e81
File diff suppressed because one or more lines are too long
2
dist/index.html
vendored
2
dist/index.html
vendored
|
|
@ -16,7 +16,7 @@
|
|||
background: #23183E;
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/index-B28_Ysnv.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-Dvo_8Nz_.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B5jzgFDg.css">
|
||||
</head>
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ export function AvatarSelectionModal({
|
|||
// حالا فایل را به سرور آپلود میکنیم
|
||||
if (fileToUpload) {
|
||||
console.log("Starting image upload...", fileToUpload.name);
|
||||
const filename = await uploadImage(fileToUpload);
|
||||
const filename = await uploadImage(fileToUpload, { requireResize: true });
|
||||
console.log("Upload result:", filename);
|
||||
|
||||
if (filename) {
|
||||
|
|
|
|||
|
|
@ -489,7 +489,7 @@ export function CommentsModal({
|
|||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-0 z-[60] flex items-center justify-center p-4"
|
||||
className="fixed inset-0 z-[130] flex items-center justify-center p-4"
|
||||
style={{ backgroundColor: "rgba(0, 0, 0, 0.7)" }}
|
||||
onClick={() => setDeleteConfirmId(null)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { useEffect, useState } from "react";
|
|||
import { getUserProfile, getCachedProfile, saveUserProfile, getUserProfileData, type UserProfile, type ProfileChallenge, type ProfileCoinTransaction, type ProfilePost } from "../../services/profileService";
|
||||
import { PostCard } from "./PostCard";
|
||||
import { AvatarSelectionModal } from "./AvatarSelectionModal";
|
||||
import { getProfileImageUrl, getFeedImageUrl, getVideoUrl, getAudioUrl, isImageFile, getMagicBagFileUrl, getAvatarUrl } from "../../services/feedService";
|
||||
import { getProfileImageUrl, getFeedImageUrl, getVideoUrl, getAudioUrl, isImageFile, getMagicBagFileUrl, getAvatarUrl, bumpAvatarCacheBust } from "../../services/feedService";
|
||||
import { ImageWithFallback } from "./figma/ImageWithFallback";
|
||||
import { usePageTracking } from "../../hooks/usePageTracking";
|
||||
import { getMissionTypeToTopicId } from "../../utils/topicMapper";
|
||||
|
|
@ -165,6 +165,9 @@ export function ProfilePage() {
|
|||
console.log("Saving profile with data:", JSON.stringify(saveData));
|
||||
const result = await saveUserProfile(saveData);
|
||||
console.log("Save profile result:", result);
|
||||
if (result) {
|
||||
bumpAvatarCacheBust();
|
||||
}
|
||||
|
||||
// بارگذاری مجدد پروفایل از سرور
|
||||
console.log("Reloading profile from server...");
|
||||
|
|
|
|||
|
|
@ -13,6 +13,15 @@ import { usePageTracking } from "../../hooks/usePageTracking";
|
|||
import { toPersianDigits } from "../../utils/persianNumberUtils";
|
||||
import chatbotAvatarIcon from "../../assets/chatbot-bot-avatar.png";
|
||||
|
||||
const createMessageId = () => {
|
||||
if (typeof globalThis !== "undefined" && globalThis.crypto?.randomUUID) {
|
||||
return globalThis.crypto.randomUUID();
|
||||
}
|
||||
|
||||
const randomPart = Math.random().toString(36).slice(2, 10);
|
||||
return `msg-${Date.now()}-${randomPart}`;
|
||||
};
|
||||
|
||||
export function PublicChatPage() {
|
||||
usePageTracking("چت عمومی");
|
||||
|
||||
|
|
@ -69,7 +78,7 @@ export function PublicChatPage() {
|
|||
publicMessages.forEach((msg) => {
|
||||
if (msg.question) {
|
||||
converted.push({
|
||||
id: crypto.randomUUID(),
|
||||
id: createMessageId(),
|
||||
type: "user",
|
||||
content: msg.question,
|
||||
timestamp: toPersianDigits(msg.datetime1),
|
||||
|
|
@ -78,7 +87,7 @@ export function PublicChatPage() {
|
|||
|
||||
if (msg.answer) {
|
||||
converted.push({
|
||||
id: crypto.randomUUID(),
|
||||
id: createMessageId(),
|
||||
type: "other",
|
||||
content: msg.answer,
|
||||
author: "ربات",
|
||||
|
|
@ -119,7 +128,7 @@ export function PublicChatPage() {
|
|||
if (!trimmedText || isSending) return;
|
||||
|
||||
const userMessage: ChatMessage = {
|
||||
id: crypto.randomUUID(),
|
||||
id: createMessageId(),
|
||||
type: "user",
|
||||
content: trimmedText,
|
||||
timestamp: new Date().toLocaleTimeString("fa-IR", {
|
||||
|
|
@ -128,7 +137,7 @@ export function PublicChatPage() {
|
|||
}),
|
||||
};
|
||||
|
||||
const loadingMessageId = crypto.randomUUID();
|
||||
const loadingMessageId = createMessageId();
|
||||
const loadingMessage: ChatMessage = {
|
||||
id: loadingMessageId,
|
||||
type: "loading",
|
||||
|
|
@ -152,7 +161,7 @@ export function PublicChatPage() {
|
|||
}
|
||||
|
||||
const botMessage: ChatMessage = {
|
||||
id: crypto.randomUUID(),
|
||||
id: createMessageId(),
|
||||
type: "other",
|
||||
content: result.answer,
|
||||
author: "ربات",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { useState } from "react";
|
||||
import type { ReactNode } from "react";
|
||||
import { getFluentEmojiCDN } from "@lobehub/fluent-emoji/es/getFluentEmojiCDN";
|
||||
|
||||
const emojiRegex =
|
||||
/(\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?)*)/gu;
|
||||
|
|
@ -9,6 +8,15 @@ interface EmojiTextProps {
|
|||
text: string;
|
||||
}
|
||||
|
||||
function getFluentEmojiCDN(emoji: string) {
|
||||
const code = Array.from(emoji)
|
||||
.map((char) => char.codePointAt(0)?.toString(16))
|
||||
.filter(Boolean)
|
||||
.join("-");
|
||||
|
||||
return `https://cdn.jsdelivr.net/gh/microsoft/fluentui-emoji/assets/${code}/3D/${code}.png`;
|
||||
}
|
||||
|
||||
function FluentEmojiImage({ emoji }: { emoji: string }) {
|
||||
const [failed, setFailed] = useState(false);
|
||||
|
||||
|
|
@ -22,7 +30,7 @@ function FluentEmojiImage({ emoji }: { emoji: string }) {
|
|||
|
||||
return (
|
||||
<img
|
||||
src={getFluentEmojiCDN(emoji, { cdn: "unpkg", type: "3d" })}
|
||||
src={getFluentEmojiCDN(emoji)}
|
||||
alt={emoji}
|
||||
loading="lazy"
|
||||
onError={() => setFailed(true)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,17 @@
|
|||
import { API_BASE_URL } from "../config/api";
|
||||
|
||||
const AVATAR_CACHE_BUST_KEY = "avatarCacheBust";
|
||||
|
||||
const getAvatarCacheBustValue = (): string => {
|
||||
return localStorage.getItem(AVATAR_CACHE_BUST_KEY) || "";
|
||||
};
|
||||
|
||||
export const bumpAvatarCacheBust = (): string => {
|
||||
const value = Date.now().toString();
|
||||
localStorage.setItem(AVATAR_CACHE_BUST_KEY, value);
|
||||
return value;
|
||||
};
|
||||
|
||||
// Get token from localStorage
|
||||
export const getAuthToken = (): string | null => {
|
||||
const accessToken = localStorage.getItem("accessToken");
|
||||
|
|
@ -143,7 +155,9 @@ export const getAvatarUrl = (personStageId: string): string => {
|
|||
// Get profile image URL from filename
|
||||
export const getProfileImageUrl = (filename: string, userStageId: string): string => {
|
||||
const token = getAuthToken();
|
||||
return `${API_BASE_URL}/api/getimage?stageID=${userStageId}&nameOrID=image&token=${token}`;
|
||||
const version = encodeURIComponent(filename || "image");
|
||||
const cacheBust = encodeURIComponent(getAvatarCacheBustValue());
|
||||
return `${API_BASE_URL}/api/getimage?stageID=${userStageId}&nameOrID=image&token=${token}&v=${version}&cb=${cacheBust}`;
|
||||
};
|
||||
|
||||
// Get image URL for feed content
|
||||
|
|
@ -637,8 +651,12 @@ export const uploadFile = async (file: File): Promise<string | null> => {
|
|||
};
|
||||
|
||||
// Upload Image
|
||||
export const uploadImage = async (file: File): Promise<string | null> => {
|
||||
export const uploadImage = async (
|
||||
file: File,
|
||||
options: { requireResize?: boolean } = {}
|
||||
): Promise<string | null> => {
|
||||
const token = getAuthToken();
|
||||
const { requireResize = false } = options;
|
||||
|
||||
if (!token) {
|
||||
console.error("uploadImage: No auth token found");
|
||||
|
|
@ -659,6 +677,10 @@ export const uploadImage = async (file: File): Promise<string | null> => {
|
|||
console.log("uploadImage: Image resized successfully");
|
||||
} catch (resizeError) {
|
||||
console.warn("uploadImage: Failed to resize image, uploading original:", resizeError);
|
||||
if (requireResize) {
|
||||
console.error("uploadImage: Resize is required for this upload. Aborting upload.");
|
||||
return null;
|
||||
}
|
||||
// در صورت خطا در ریسایز، فایل اصلی را آپلود میکنیم
|
||||
fileToUpload = file;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user