2.2.6.5114514
This commit is contained in:
23 files changed
+4497
-49
No files matched your search
@@ -4,3 +4,4 @@ node_modules
|
||||
devAssets
|
||||
|
||||
.DS_Store
|
||||
android
|
||||
@@ -6,6 +6,7 @@ WORKDIR /src
|
||||
COPY .npmrc package.json package-lock.json /src/
|
||||
RUN npm ci
|
||||
COPY . /src/
|
||||
ENV NODE_OPTIONS=--max_old_space_size=4096
|
||||
RUN npm run build
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
@@ -0,0 +1,10 @@
|
||||
import { CapacitorConfig } from '@capacitor/cli';
|
||||
|
||||
const config: CapacitorConfig = {
|
||||
appId: 'today.icarus.cinny',
|
||||
appName: 'Cinny',
|
||||
webDir: 'dist',
|
||||
bundledWebRuntime: false,
|
||||
};
|
||||
|
||||
export default config;
|
||||
Generated
+4151
-29
File diff suppressed because it is too large.
Load diff
+6
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cinny",
|
||||
"version": "2.2.4",
|
||||
"version": "2.2.6",
|
||||
"description": "Yet another matrix client",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
@@ -19,6 +19,8 @@
|
||||
"author": "Ajay Bura",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@capacitor/android": "4.7.1",
|
||||
"@capacitor/core": "4.7.1",
|
||||
"@fontsource/inter": "4.5.14",
|
||||
"@fontsource/roboto": "4.5.8",
|
||||
"@khanacademy/simple-markdown": "0.8.6",
|
||||
@@ -40,7 +42,7 @@
|
||||
"katex": "0.16.4",
|
||||
"linkify-html": "4.0.2",
|
||||
"linkifyjs": "4.0.2",
|
||||
"matrix-js-sdk": "22.0.0",
|
||||
"matrix-js-sdk": "24.0.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.2",
|
||||
"react-autosize-textarea": "7.1.0",
|
||||
@@ -56,6 +58,8 @@
|
||||
"twemoji": "14.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/assets": "2.0.4",
|
||||
"@capacitor/cli": "4.7.1",
|
||||
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
|
||||
"@rollup/plugin-inject": "5.0.3",
|
||||
"@rollup/plugin-wasm": "6.1.1",
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 800 800" style="enable-background:new 0 0 800 800;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{stroke:#000000;stroke-width:9;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M405,442.5H244.8v160.2h-67.1V442.5H17.5v-67.1h160.2V215.2h67.1v160.2H405V442.5z"/>
|
||||
<path class="st0" d="M757,697.8h-75.1V237.2c-30.4,20.2-77.4,30.4-141,30.4v-59.1c91.9,0,144.6-35.4,158.2-106.3H757V697.8z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 688 B |
@@ -50,6 +50,7 @@ import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg';
|
||||
import CmdIC from '../../../../public/res/ic/outlined/cmd.svg';
|
||||
import BinIC from '../../../../public/res/ic/outlined/bin.svg';
|
||||
import TransIC from '../../../../public/res/ic/outlined/translate.svg';
|
||||
import repeatIC from '../../../../public/res/ic/outlined/repeat.svg';
|
||||
|
||||
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
|
||||
import { getBlobSafeMimeType } from '../../../util/mimetypes';
|
||||
@@ -552,6 +553,14 @@ function handleTextTranslate(mEvent) {
|
||||
openTextTranslate(mEvent);
|
||||
}
|
||||
|
||||
async function handleRepeat(mEvent){
|
||||
console.log(mEvent);
|
||||
const opt = {};
|
||||
opt.msgType = 'm.text';
|
||||
initMatrix.roomsInput.setMessage(mEvent.sender.roomId, mEvent.clearEvent.content.body);
|
||||
await initMatrix.roomsInput.sendInput(mEvent.sender.roomId, opt);
|
||||
}
|
||||
|
||||
const MessageOptions = React.memo(({ roomTimeline, mEvent, edit, reply }) => {
|
||||
const { roomId, room } = roomTimeline;
|
||||
const mx = initMatrix.matrixClient;
|
||||
@@ -591,6 +600,9 @@ const MessageOptions = React.memo(({ roomTimeline, mEvent, edit, reply }) => {
|
||||
<MenuItem iconSrc={TransIC} onClick={() => handleTextTranslate(mEvent)}>
|
||||
Translate
|
||||
</MenuItem>
|
||||
<MenuItem iconSrc={repeatIC} onClick={() => handleRepeat(mEvent)}>
|
||||
Repeat
|
||||
</MenuItem>
|
||||
{(canIRedact || senderId === mx.getUserId()) && (
|
||||
<>
|
||||
<MenuBorder />
|
||||
|
||||
@@ -188,6 +188,7 @@ function RoomViewInput({ roomId, roomTimeline, viewEvent }) {
|
||||
}, [roomId]);
|
||||
|
||||
const sendBody = async (body, options) => {
|
||||
console.log(options)
|
||||
const opt = options ?? {};
|
||||
if (!opt.msgType) opt.msgType = 'm.text';
|
||||
if (typeof opt.autoMarkdown !== 'boolean') opt.autoMarkdown = true;
|
||||
@@ -218,7 +219,7 @@ function RoomViewInput({ roomId, roomTimeline, viewEvent }) {
|
||||
confirmDialog('Invalid Command', `"${cmdName}" is not a valid command.`, 'Alright');
|
||||
return;
|
||||
}
|
||||
if (['me', 'shrug', 'plain'].includes(cmdName)) {
|
||||
if (['me', 'shrug', 'plain', 'rainbow'].includes(cmdName)) {
|
||||
commands[cmdName].exe(roomId, cmdData, sendBody);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,57 @@ export function processMxidAndReason(data) {
|
||||
};
|
||||
}
|
||||
|
||||
function rainbowText(str) {
|
||||
// 定义渐变颜色数组
|
||||
const startColor = [255, 0, 0]; // 红色
|
||||
const middleColor = [0, 255, 0]; // 绿色
|
||||
const endColor = [0, 0, 255]; // 蓝色
|
||||
const numSteps = str.length - 1;
|
||||
const stepsToGreen = Math.round(numSteps / 2);
|
||||
const stepsToBlue = numSteps - stepsToGreen;
|
||||
const stepToGreen = [
|
||||
(middleColor[0] - startColor[0]) / stepsToGreen,
|
||||
(middleColor[1] - startColor[1]) / stepsToGreen,
|
||||
(middleColor[2] - startColor[2]) / stepsToGreen
|
||||
];
|
||||
const stepToBlue = [
|
||||
(endColor[0] - middleColor[0]) / stepsToBlue,
|
||||
(endColor[1] - middleColor[1]) / stepsToBlue,
|
||||
(endColor[2] - middleColor[2]) / stepsToBlue
|
||||
];
|
||||
|
||||
// 生成 HTML 字符串
|
||||
let html = '';
|
||||
const currentColor = startColor.slice();
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
// 转换颜色为 16 进制字符串
|
||||
const hexColor = `#${ currentColor.map(c => {
|
||||
const hex = Math.round(c).toString(16);
|
||||
return hex.length === 1 ? `0${ hex}` : hex;
|
||||
}).join('')}`;
|
||||
|
||||
// 将字符包装在 <font> 标签中,并设置颜色
|
||||
const fontTag = `<font color="${hexColor}">${str[i]}</font>`;
|
||||
html += fontTag;
|
||||
|
||||
// 计算下一个颜色
|
||||
if (i < stepsToGreen) {
|
||||
currentColor[0] += stepToGreen[0];
|
||||
currentColor[1] += stepToGreen[1];
|
||||
currentColor[2] += stepToGreen[2];
|
||||
} else {
|
||||
currentColor[0] += stepToBlue[0];
|
||||
currentColor[1] += stepToBlue[1];
|
||||
currentColor[2] += stepToBlue[2];
|
||||
}
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const commands = {
|
||||
me: {
|
||||
name: 'me',
|
||||
@@ -198,6 +249,14 @@ const commands = {
|
||||
roomActions.convertToRoom(roomId);
|
||||
},
|
||||
},
|
||||
rainbow: {
|
||||
name: 'rainbow',
|
||||
description: 'Rainbow text',
|
||||
exe: (roomId, data, onSuccess) => onSuccess(
|
||||
data,
|
||||
{ msgtype:'m.text', format: 'org.matrix.custom.html', formatted_body: rainbowText(data) },
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
function openHelpDialog() {
|
||||
|
||||
@@ -42,11 +42,15 @@ import BellIC from '../../../../public/res/ic/outlined/bell.svg';
|
||||
import InfoIC from '../../../../public/res/ic/outlined/info.svg';
|
||||
import PowerIC from '../../../../public/res/ic/outlined/power.svg';
|
||||
import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
|
||||
import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
|
||||
|
||||
import CinnySVG from '../../../../public/res/svg/cinny.svg';
|
||||
import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
|
||||
|
||||
import '../../i18n.jsx'
|
||||
import PeopleSelector from '../../molecules/people-selector/PeopleSelector';
|
||||
import colorMXID from '../../../util/colorMXID';
|
||||
import { openReusableDialog } from '../../../client/action/navigation';
|
||||
|
||||
let capabilities = {
|
||||
privateReadReceipts: false,
|
||||
@@ -101,6 +105,9 @@ function AppearanceSection() {
|
||||
{ text: 'Silver' },
|
||||
{ text: 'Dark' },
|
||||
{ text: 'Butter' },
|
||||
{ text: 'NGA'},
|
||||
{ text: 'NGA Green'},
|
||||
{ text: '?'}
|
||||
]}
|
||||
onSelect={(index) => {
|
||||
if (settings.useSystemTheme) toggleSystemTheme();
|
||||
@@ -355,10 +362,10 @@ function AboutSection() {
|
||||
<div>
|
||||
<Text variant="h2" weight="medium">
|
||||
Cinny Mod
|
||||
<span className="text text-b3" style={{ margin: '0 var(--sp-extra-tight)' }}>{`v${cons.version}.52`}</span>
|
||||
<span className="text text-b3" style={{ margin: '0 var(--sp-extra-tight)' }}>{`v${cons.version}.5114514`}</span>
|
||||
</Text>
|
||||
<Text>Yet another matrix client</Text>
|
||||
<Text>Modded By WHK with magic & love</Text>
|
||||
<Text>Modded By WHK(a.k.a CroiX) with magic & love</Text>
|
||||
|
||||
<div className="settings-about__btns">
|
||||
<Button onClick={() => window.open('https://github.com/ajbura/cinny')}>Source code</Button>
|
||||
@@ -468,6 +475,51 @@ function Settings() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSwitchUsers = async () => {
|
||||
const loggedInUsers = JSON.parse(window.localStorage.getItem("loggedInUsers"));
|
||||
|
||||
const renderUserSwitcher = () => (
|
||||
<div>
|
||||
{
|
||||
loggedInUsers.map((userId) => {
|
||||
const mx = initMatrix.matrixClient;
|
||||
const user = mx.getUser(userId);
|
||||
const avatarUrl = user.avatarUrl ? mx.mxcUrlToHttp(user.avatarUrl, 80, 80, 'crop') : null;
|
||||
return (
|
||||
<PeopleSelector
|
||||
key={userId}
|
||||
onClick={() => {
|
||||
if (userId !== window.localStorage.getItem("currentUser")) {
|
||||
window.localStorage.setItem("currentUser", userId);
|
||||
window.location.reload();
|
||||
}
|
||||
}}
|
||||
name={user.displayName}
|
||||
avatarSrc={avatarUrl}
|
||||
color={colorMXID(userId)}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
<Button
|
||||
variant="caution"
|
||||
iconSrc={AddUserIC}
|
||||
onClick={() => {
|
||||
window.localStorage.removeItem("currentUser");
|
||||
window.location.reload();
|
||||
}}
|
||||
>
|
||||
Add user
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
await openReusableDialog(
|
||||
<Text variant="s1" weight="medium">Switch users</Text>,
|
||||
renderUserSwitcher,
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<PopupWindow
|
||||
isOpen={isOpen}
|
||||
@@ -475,6 +527,9 @@ function Settings() {
|
||||
title={<Text variant="s1" weight="medium" primary>{t("Settings")}</Text>}
|
||||
contentOptions={(
|
||||
<>
|
||||
<Button variant="caution" iconSrc={AddUserIC} onClick={handleSwitchUsers}>
|
||||
Switch users
|
||||
</Button>
|
||||
<Button variant="danger" iconSrc={PowerIC} onClick={handleLogout}>
|
||||
Logout
|
||||
</Button>
|
||||
|
||||
@@ -25,6 +25,8 @@ import EyeIC from '../../../../public/res/ic/outlined/eye.svg';
|
||||
import EyeBlindIC from '../../../../public/res/ic/outlined/eye-blind.svg';
|
||||
import CinnySvg from '../../../../public/res/svg/cinny.svg';
|
||||
import SSOButtons from '../../molecules/sso-buttons/SSOButtons';
|
||||
import colorMXID from '../../../util/colorMXID';
|
||||
import PeopleSelector from '../../molecules/people-selector/PeopleSelector';
|
||||
|
||||
const LOCALPART_SIGNUP_REGEX = /^[a-z0-9_\-.=/]+$/;
|
||||
const BAD_LOCALPART_ERROR = 'Username can only contain characters a-z, 0-9, or \'=_-./\'';
|
||||
@@ -537,13 +539,14 @@ function AuthCard() {
|
||||
function Auth() {
|
||||
const [loginToken, setLoginToken] = useState(getUrlPrams('loginToken'));
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
useEffect(async () => {
|
||||
if (!loginToken) return;
|
||||
if (localStorage.getItem(cons.secretKey.BASE_URL) === undefined) {
|
||||
if (window.userLocalStorage.getItem(cons.secretKey.BASE_URL) === undefined) {
|
||||
setLoginToken(null);
|
||||
return;
|
||||
}
|
||||
const baseUrl = localStorage.getItem(cons.secretKey.BASE_URL);
|
||||
const baseUrl = window.userLocalStorage.getItem(cons.secretKey.BASE_URL);
|
||||
try {
|
||||
await auth.loginWithToken(baseUrl, loginToken);
|
||||
|
||||
@@ -567,6 +570,37 @@ function Auth() {
|
||||
<Text variant="h2" weight="medium">Cinny</Text>
|
||||
</TitleWrapper>
|
||||
</Header>
|
||||
{(() => {
|
||||
let loggedInUsers = JSON.parse(window.localStorage.getItem("loggedInUsers"));
|
||||
if (!loggedInUsers) {
|
||||
// 检查currentUser是否存在
|
||||
const currentUser = window.localStorage.getItem('cinny_user_id');
|
||||
if(currentUser){
|
||||
// 开始迁移
|
||||
window.localStorage.setItem('loggedInUsers', JSON.stringify([currentUser]));
|
||||
window.localStorage.setItem('currentUser', currentUser);
|
||||
window.localStorage.setItem(`${currentUser}.cinny_access_token`, window.localStorage.getItem('cinny_access_token'));
|
||||
window.localStorage.setItem(`${currentUser}.cinny_device_id`, window.localStorage.getItem('cinny_device_id'));
|
||||
window.localStorage.setItem(`${currentUser}.cinny_hs_base_url`, window.localStorage.getItem('cinny_hs_base_url'));
|
||||
window.localStorage.setItem(`${currentUser}.cinny_user_id`, window.localStorage.getItem('cinny_user_id'));
|
||||
} else{
|
||||
loggedInUsers = []
|
||||
}
|
||||
}
|
||||
return (
|
||||
loggedInUsers.map((userId) => (
|
||||
<PeopleSelector
|
||||
key={userId}
|
||||
onClick={() => {
|
||||
window.localStorage.setItem("currentUser", userId);
|
||||
window.location.reload();
|
||||
}}
|
||||
name={userId}
|
||||
color={colorMXID(userId)}
|
||||
/>
|
||||
))
|
||||
);
|
||||
})()}
|
||||
<div className="auth-card__content">
|
||||
<AuthCard />
|
||||
</div>
|
||||
|
||||
@@ -89,7 +89,9 @@ function Client() {
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
|
||||
<div className="loading-display">
|
||||
{/* <div className="watermark">Cinny Mod</div> */}
|
||||
<div className="loading__menu">
|
||||
<ContextMenu
|
||||
placement="bottom"
|
||||
@@ -170,6 +172,18 @@ function Client() {
|
||||
initMatrix.roomsInput.emit(cons.events.roomsInput.ATTACHMENT_SET, file);
|
||||
}
|
||||
|
||||
// 盲水印实验性特性
|
||||
// const watermark = document.querySelector('.watermark');
|
||||
// for (let i = 0; i < window.innerHeight / watermark.offsetHeight + 1; i += 0.25) {
|
||||
// for (let j = 0; j < window.innerWidth / watermark.offsetWidth + 1; j += 0.25) {
|
||||
// const clone = watermark.cloneNode(true);
|
||||
// clone.style.top = i * watermark.offsetHeight + 'px';
|
||||
// clone.style.left = j * watermark.offsetWidth + 'px';
|
||||
// document.body.appendChild(clone);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="client-container"
|
||||
@@ -178,6 +192,7 @@ function Client() {
|
||||
onDragLeave={handleDragLeave}
|
||||
onDrop={handleDrop}
|
||||
>
|
||||
{/* <div className="watermark">Cinny Mod</div> */}
|
||||
<div className={`navigation__wrapper ${settings.hideNavigation && roomSelected ? toggleHidden : ''}`} ref={navWrapperRef}>
|
||||
<Navigation />
|
||||
</div>
|
||||
@@ -191,6 +206,7 @@ function Client() {
|
||||
<DragDrop isOpen={dragCounter !== 0} />
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default Client;
|
||||
@@ -1,11 +1,19 @@
|
||||
import * as sdk from 'matrix-js-sdk';
|
||||
import cons from '../state/cons';
|
||||
import NamespacedStorage from '../state/NamespacedStorage';
|
||||
|
||||
function updateLocalStore(accessToken, deviceId, userId, baseUrl) {
|
||||
localStorage.setItem(cons.secretKey.ACCESS_TOKEN, accessToken);
|
||||
localStorage.setItem(cons.secretKey.DEVICE_ID, deviceId);
|
||||
localStorage.setItem(cons.secretKey.USER_ID, userId);
|
||||
localStorage.setItem(cons.secretKey.BASE_URL, baseUrl);
|
||||
window.localStorage.setItem("currentUser", userId);
|
||||
const loggedInUsers = new Set(JSON.parse(window.localStorage.getItem("loggedInUsers")));
|
||||
loggedInUsers.add(userId);
|
||||
window.localStorage.setItem("loggedInUsers", JSON.stringify(Array.from(loggedInUsers)));
|
||||
|
||||
window.userLocalStorage = new NamespacedStorage(userId, window.localStorage);
|
||||
|
||||
window.userLocalStorage.setItem(cons.secretKey.ACCESS_TOKEN, accessToken);
|
||||
window.userLocalStorage.setItem(cons.secretKey.DEVICE_ID, deviceId);
|
||||
window.userLocalStorage.setItem(cons.secretKey.USER_ID, userId);
|
||||
window.userLocalStorage.setItem(cons.secretKey.BASE_URL, baseUrl);
|
||||
}
|
||||
|
||||
function createTemporaryClient(baseUrl) {
|
||||
@@ -14,7 +22,7 @@ function createTemporaryClient(baseUrl) {
|
||||
|
||||
async function startSsoLogin(baseUrl, type, idpId) {
|
||||
const client = createTemporaryClient(baseUrl);
|
||||
localStorage.setItem(cons.secretKey.BASE_URL, client.baseUrl);
|
||||
window.userLocalStorage.setItem(cons.secretKey.BASE_URL, client.baseUrl);
|
||||
window.location.href = client.getSsoLoginUrl(window.location.href, type, idpId);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,12 @@ class InitMatrix extends EventEmitter {
|
||||
// ignore if failed to logout
|
||||
}
|
||||
await this.matrixClient.clearStores();
|
||||
window.localStorage.clear();
|
||||
window.userLocalStorage.clear();
|
||||
const currentUser = window.localStorage.getItem("currentUser");
|
||||
const loggedInUsers = new Set(JSON.parse(window.localStorage.getItem("loggedInUsers")));
|
||||
loggedInUsers.delete(currentUser);
|
||||
window.localStorage.setItem("loggedInUsers", JSON.stringify(loggedInUsers));
|
||||
window.localStorage.removeItem("currentUser");
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
class NamespacedStorage {
|
||||
#namespace;
|
||||
|
||||
#storage;
|
||||
|
||||
#cache;
|
||||
|
||||
constructor(namespace, storage) {
|
||||
this.#namespace = namespace;
|
||||
this.#storage = storage;
|
||||
|
||||
this.#cache = new Set();
|
||||
for (let i = 0; i < this.#storage.length; i++) {
|
||||
let key = this.#storage.key(i);
|
||||
if (key.startsWith(`${this.#namespace}.`)) {
|
||||
this.#cache.add(key.replace(`${this.#namespace}.`, ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
key(n) {
|
||||
return this.#cache[n];
|
||||
}
|
||||
|
||||
getItem(key) {
|
||||
return this.#storage.getItem(`${this.#namespace}.${key}`);
|
||||
}
|
||||
|
||||
setItem(key, value) {
|
||||
this.#storage.setItem(`${this.#namespace}.${key}`, value);
|
||||
this.#cache.add(key);
|
||||
}
|
||||
|
||||
removeItem(key) {
|
||||
this.#storage.removeItem(`${this.#namespace}.${key}`);
|
||||
this.#cache.delete(key);
|
||||
}
|
||||
|
||||
clear() {
|
||||
for (let key of this.#cache) {
|
||||
this.removeItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default NamespacedStorage;
|
||||
@@ -298,7 +298,9 @@ class Notifications extends EventEmitter {
|
||||
_deletePopupRoomNotis(roomId) {
|
||||
this.roomIdToPopupNotis.get(roomId)?.forEach((n) => {
|
||||
this.eventIdToPopupNoti.delete(n.tag);
|
||||
n.close();
|
||||
if(n.close){
|
||||
n.close();
|
||||
}
|
||||
});
|
||||
this.roomIdToPopupNotis.delete(roomId);
|
||||
}
|
||||
|
||||
@@ -211,6 +211,11 @@ class RoomsInput extends EventEmitter {
|
||||
content.formatted_body = body.html;
|
||||
}
|
||||
|
||||
if(options.format === 'org.matrix.custom.html'){
|
||||
content.format = 'org.matrix.custom.html';
|
||||
content.formatted_body = options.formatted_body;
|
||||
}
|
||||
|
||||
if (edit) {
|
||||
content['m.new_content'] = { ...content };
|
||||
content['m.relates_to'] = {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import NamespacedStorage from './NamespacedStorage';
|
||||
import cons from './cons';
|
||||
|
||||
function getSecret(key) {
|
||||
return localStorage.getItem(key);
|
||||
const user = global.localStorage.getItem("currentUser");
|
||||
const storage = new NamespacedStorage(user, global.localStorage);
|
||||
return storage.getItem(key);
|
||||
}
|
||||
|
||||
const isAuthenticated = () => getSecret(cons.secretKey.ACCESS_TOKEN) !== null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const cons = {
|
||||
version: '2.2.4',
|
||||
version: '2.2.6',
|
||||
secretKey: {
|
||||
ACCESS_TOKEN: 'cinny_access_token',
|
||||
DEVICE_ID: 'cinny_device_id',
|
||||
|
||||
@@ -4,7 +4,7 @@ import appDispatcher from '../dispatcher';
|
||||
import cons from './cons';
|
||||
|
||||
function getSettings() {
|
||||
const settings = localStorage.getItem('settings');
|
||||
const settings = window.localStorage.getItem('settings');
|
||||
if (settings === null) return null;
|
||||
return JSON.parse(settings);
|
||||
}
|
||||
@@ -13,14 +13,14 @@ function setSettings(key, value) {
|
||||
let settings = getSettings();
|
||||
if (settings === null) settings = {};
|
||||
settings[key] = value;
|
||||
localStorage.setItem('settings', JSON.stringify(settings));
|
||||
window.localStorage.setItem('settings', JSON.stringify(settings));
|
||||
}
|
||||
|
||||
class Settings extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.themes = ['', 'silver-theme', 'dark-theme', 'butter-theme'];
|
||||
this.themes = ['', 'silver-theme', 'dark-theme', 'butter-theme', 'nga-theme', 'nga-green-theme', 'troll'];
|
||||
this.themeIndex = this.getThemeIndex();
|
||||
this.translationIndex = this.getTranslationAPIIndex();
|
||||
this.translationLanguage = this.getTranslationLanguage();
|
||||
|
||||
@@ -306,6 +306,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
// .watermark {
|
||||
// position: fixed;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// z-index: 9999;
|
||||
// font-size: 24px;
|
||||
// color: #ccc;
|
||||
// text-align: center;
|
||||
// opacity: 0.03;
|
||||
// transform: rotate(-45deg);
|
||||
// transform-origin: 0 0;
|
||||
// user-select: none;
|
||||
// pointer-events: none;
|
||||
// }
|
||||
|
||||
|
||||
.butter-theme {
|
||||
/* background color | --bg-[background type]: value */
|
||||
--bg-surface: hsl(64, 6%, 14%);
|
||||
@@ -331,6 +349,40 @@
|
||||
--ic-surface-low: rgba(255, 251, 222, 64%);
|
||||
}
|
||||
|
||||
.nga-theme {
|
||||
/* background color | --bg-[background type]: value */
|
||||
--bg-surface: rgb(254,248,231);
|
||||
--bg-surface-transparent: hsla(0, 0%, 95%, 0);
|
||||
--bg-surface-low: rgb(244,232,202);
|
||||
--bg-surface-low-transparent: hsla(0, 0%, 91%, 0);
|
||||
--bg-surface-extra-low: rgb(244,232,202);
|
||||
--bg-surface-extra-low-transparent: hsla(0, 0%, 91%, 0);
|
||||
--bg-positive: rgb(214, 189, 127);
|
||||
--bg-primary: rgb(86, 23, 1);
|
||||
--bg-primary-hover: rgb(180, 116, 98);
|
||||
--bg-primary-active: rgb(180, 116, 98);
|
||||
--ic-surface-normal: rgb(86, 23, 1);
|
||||
}
|
||||
|
||||
.nga-green-theme {
|
||||
/* background color | --bg-[background type]: value */
|
||||
--bg-surface: rgb(241,247,245);
|
||||
--bg-surface-transparent: hsla(0, 0%, 95%, 0);
|
||||
--bg-surface-low: rgb(226,239,235);
|
||||
--bg-surface-low-transparent: hsla(0, 0%, 91%, 0);
|
||||
--bg-surface-extra-low: rgb(226,239,235);
|
||||
--bg-surface-extra-low-transparent: hsla(0, 0%, 91%, 0);
|
||||
--bg-positive: rgb(212,222,219);
|
||||
--bg-primary: rgb(42,67,73);
|
||||
--bg-primary-hover: rgb(125,162,160);
|
||||
--bg-primary-active: rgb(125,162,160);
|
||||
--ic-surface-normal: rgb(42,67,73);
|
||||
}
|
||||
|
||||
.troll {
|
||||
filter: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='3d-glasses' x='0' y='0' width='1' height='1'%3E%3CfeGaussianBlur in='SourceGraphic' stdDeviation='2' /%3E%3CfeColorMatrix values='1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 100 0' /%3E%3CfeOffset dx='5' dy='5' /%3E%3CfeColorMatrix values='0.5 0 0 0 0 0 0.5 0 0 0 0 0 0.5 0 0 0 0 0 1 0' /%3E%3CfeBlend mode='multiply' in2='SourceGraphic' /%3E%3C/filter%3E%3C/svg%3E#3d-glasses");
|
||||
}
|
||||
|
||||
.font-primary {
|
||||
font-family: var(--font-primary);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import parse from 'html-react-parser';
|
||||
import twemoji from 'twemoji';
|
||||
import { sanitizeText } from './sanitize';
|
||||
|
||||
export const TWEMOJI_BASE_URL = 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/';
|
||||
export const TWEMOJI_BASE_URL = 'https://fastly.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/';
|
||||
|
||||
const Math = lazy(() => import('../app/atoms/math/Math'));
|
||||
|
||||
|
||||
Reference in new issue
Block a user