Compare commits

..

1 commit

Author SHA1 Message Date
e75fef6ba3
Add room topic 2023-03-31 18:16:02 -05:00
13 changed files with 134 additions and 112 deletions

View file

@ -1,4 +0,0 @@
{
"schemaVersion": 2,
"dockerfilePath": "./Dockerfile"
}

View file

@ -102,6 +102,6 @@
<audio id="inviteSound">
<source src="./public/sound/invite.ogg" type="audio/ogg" />
</audio>
<script type="module" src="./src/index.tsx"></script>
<script type="module" src="./src/index.jsx"></script>
</body>
</html>

22
package-lock.json generated
View file

@ -14,7 +14,6 @@
"@khanacademy/simple-markdown": "0.8.6",
"@matrix-org/olm": "3.2.14",
"@tippyjs/react": "4.2.6",
"@types/flux": "3.1.11",
"blurhash": "2.0.4",
"browser-encrypt-attachment": "0.3.0",
"dateformat": "5.0.3",
@ -44,7 +43,6 @@
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
"@rollup/plugin-inject": "5.0.3",
"@rollup/plugin-wasm": "6.1.1",
"@types/dateformat": "5.0.0",
"@types/node": "18.11.18",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.9",
@ -1117,12 +1115,6 @@
"react-dom": ">=16.8"
}
},
"node_modules/@types/dateformat": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/dateformat/-/dateformat-5.0.0.tgz",
"integrity": "sha512-SZg4JdHIWHQGEokbYGZSDvo5wA4TLYPXaqhigs/wH+REDOejcJzgH+qyY+HtEUtWOZxEUkbhbdYPqQDiEgrXeA==",
"dev": true
},
"node_modules/@types/estree": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
@ -1134,20 +1126,6 @@
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
},
"node_modules/@types/fbemitter": {
"version": "2.0.32",
"resolved": "https://registry.npmjs.org/@types/fbemitter/-/fbemitter-2.0.32.tgz",
"integrity": "sha512-Hwq28bBlbmfCgLnNJvjl5ssTrbZCTSblI4vqPpqZrbbEL8vn5l2UivxhlMYfUY7a4SR8UB6RKoLjOZfljqAa6g=="
},
"node_modules/@types/flux": {
"version": "3.1.11",
"resolved": "https://registry.npmjs.org/@types/flux/-/flux-3.1.11.tgz",
"integrity": "sha512-Aq4UB1ZqAKcPbhB0GpgMw2sntvOh71he9tjz53TLKrI7rw3Y3LxCW5pTYY9IV455hQapm4pmxFjpqlWOs308Yg==",
"dependencies": {
"@types/fbemitter": "*",
"@types/react": "*"
}
},
"node_modules/@types/json-schema": {
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",

View file

@ -9,7 +9,7 @@
"scripts": {
"start": "vite",
"build": "vite build",
"lint": "npm run check:eslint && npm run check:prettier",
"lint": "yarn check:eslint && yarn check:prettier",
"check:eslint": "eslint src/*",
"check:prettier": "prettier --check .",
"fix:prettier": "prettier --write .",
@ -24,7 +24,6 @@
"@khanacademy/simple-markdown": "0.8.6",
"@matrix-org/olm": "3.2.14",
"@tippyjs/react": "4.2.6",
"@types/flux": "3.1.11",
"blurhash": "2.0.4",
"browser-encrypt-attachment": "0.3.0",
"dateformat": "5.0.3",
@ -54,7 +53,6 @@
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
"@rollup/plugin-inject": "5.0.3",
"@rollup/plugin-wasm": "6.1.1",
"@types/dateformat": "5.0.0",
"@types/node": "18.11.18",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.9",

View file

@ -1,18 +1,14 @@
import React from "react";
import PropTypes from "prop-types";
import dateFormat from "dateformat";
import { isInSameDay } from "../../../util/common";
export interface TimeProps {
timestamp: number;
fullTime?: boolean;
}
function Time({ timestamp, fullTime }: TimeProps) {
function Time({ timestamp, fullTime }) {
const date = new Date(timestamp);
const formattedFullTime = dateFormat(date, "dd mmmm yyyy, hh:MM TT");
let formattedDateTime = formattedFullTime;
let formattedDate = formattedFullTime;
if (!fullTime) {
const compareDate = new Date();
@ -20,21 +16,18 @@ function Time({ timestamp, fullTime }: TimeProps) {
compareDate.setDate(compareDate.getDate() - 1);
const isYesterday = isInSameDay(date, compareDate);
const dtf = new Intl.DateTimeFormat();
const formattedDate = dtf.format(date);
formattedDateTime = dateFormat(
formattedDate = dateFormat(
date,
isToday || isYesterday ? "hh:MM TT" : formattedDate
isToday || isYesterday ? "hh:MM TT" : "dd/mm/yyyy"
);
if (isYesterday) {
formattedDateTime = `Yesterday, ${formattedDateTime}`;
formattedDate = `Yesterday, ${formattedDate}`;
}
}
return (
<time dateTime={date.toISOString()} title={formattedFullTime}>
{formattedDateTime}
{formattedDate}
</time>
);
}
@ -43,4 +36,9 @@ Time.defaultProps = {
fullTime: false,
};
Time.propTypes = {
timestamp: PropTypes.number.isRequired,
fullTime: PropTypes.bool,
};
export default Time;

View file

@ -97,14 +97,6 @@ function Home({ spaceId }) {
/>
)}
{roomIds.length !== 0 && (
<RoomsCategory
name="Rooms"
roomIds={roomIds.sort(roomIdByAtoZ)}
drawerPostie={drawerPostie}
/>
)}
{directIds.length !== 0 && (
<RoomsCategory
name="People"

View file

@ -48,7 +48,7 @@
}
& .room-selector {
width: calc(100% - 2 * var(--sp-extra-tight));
@include dir.side(margin, auto, auto);
width: calc(100% - var(--sp-extra-tight));
@include dir.side(margin, auto, 0);
}
}

View file

@ -3,9 +3,8 @@
@use "../../partials/screen";
.room-header__btn {
min-width: 0;
@extend .cp-fx__row--s-c;
@include dir.side(margin, 0, auto);
@include dir.side(margin, 0, var(--sp-extra-tight));
border-radius: var(--bo-radius);
cursor: pointer;
@ -27,21 +26,54 @@
}
}
.room-header__topic {
min-width: 0;
display: flex;
align-items: center;
@include dir.side(margin, 0, auto);
p {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.room-header__drawer-btn {
flex: 0;
@include screen.smallerThan(tabletBreakpoint) {
display: none;
}
}
.room-header__members-btn {
flex: 0;
@include screen.biggerThan(tabletBreakpoint) {
display: none;
}
}
.room-header__back-btn {
flex: 0;
@include dir.side(margin, 0, var(--sp-tight));
@include screen.biggerThan(mobileBreakpoint) {
display: none;
}
}
.room-header__left {
display: flex;
flex-shrink: 1;
min-width: 0;
}
.room-header__right {
display: flex;
flex-grow: 1;
justify-content: flex-end;
min-width: 0;
}

View file

@ -1,5 +1,4 @@
import React, { useEffect, useRef } from "react";
import PropTypes from "prop-types";
import "./RoomViewHeader.scss";
import { twemojify } from "../../../util/twemojify";
@ -33,16 +32,26 @@ import BackArrowIC from "../../../../public/res/ic/outlined/chevron-left.svg";
import { useForceUpdate } from "../../hooks/useForceUpdate";
function RoomViewHeader({ roomId }) {
interface RoomViewHeaderProps {
roomId: string;
}
function RoomViewHeader({ roomId }: RoomViewHeaderProps) {
const [, forceUpdate] = useForceUpdate();
const mx = initMatrix.matrixClient;
const isDM = initMatrix.roomList.directs.has(roomId);
const room = mx.getRoom(roomId);
let avatarSrc = room.getAvatarUrl(mx.baseUrl, 36, 36, "crop");
avatarSrc = isDM
? room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 36, 36, "crop")
? room
.getAvatarFallbackMember()
?.getAvatarUrl(mx.baseUrl, 36, 36, "crop", true, false)
: avatarSrc;
const roomName = room.name;
const { name: roomName, currentState } = room;
const roomTopic = currentState
.getStateEvents("m.room.topic")[0]
?.getContent().topic;
const roomHeaderBtnRef = useRef(null);
useEffect(() => {
@ -89,61 +98,69 @@ function RoomViewHeader({ roomId }) {
return (
<Header>
<IconButton
src={BackArrowIC}
className="room-header__back-btn"
tooltip="Return to navigation"
onClick={() => openNavigation()}
/>
<button
ref={roomHeaderBtnRef}
className="room-header__btn"
onClick={() => toggleRoomSettings()}
type="button"
onMouseUp={(e) => blurOnBubbling(e, ".room-header__btn")}
>
<Avatar
imageSrc={avatarSrc}
text={roomName}
bgColor={colorMXID(roomId)}
size="small"
/>
<TitleWrapper>
<Text variant="h2" weight="medium" primary>
{twemojify(roomName)}
</Text>
</TitleWrapper>
<RawIcon src={ChevronBottomIC} />
</button>
{mx.isRoomEncrypted(roomId) === false && (
<div class="room-header__left">
<IconButton
onClick={() => toggleRoomSettings(tabText.SEARCH)}
tooltip="Search"
src={SearchIC}
src={BackArrowIC}
className="room-header__back-btn"
tooltip="Return to navigation"
onClick={() => openNavigation()}
/>
)}
<IconButton
className="room-header__drawer-btn"
onClick={togglePeopleDrawer}
tooltip="People"
src={UserIC}
/>
<IconButton
className="room-header__members-btn"
onClick={() => toggleRoomSettings(tabText.MEMBERS)}
tooltip="Members"
src={UserIC}
/>
<IconButton
onClick={openRoomOptions}
tooltip="Options"
src={VerticalMenuIC}
/>
<button
ref={roomHeaderBtnRef}
className="room-header__btn"
onClick={() => toggleRoomSettings()}
type="button"
onMouseUp={(e) => blurOnBubbling(e, ".room-header__btn")}
>
<Avatar
imageSrc={avatarSrc}
text={roomName}
bgColor={colorMXID(roomId)}
size="small"
/>
<TitleWrapper>
<Text variant="h2" weight="medium" primary>
{twemojify(roomName)}
</Text>
</TitleWrapper>
<RawIcon src={ChevronBottomIC} />
</button>
<div className="room-header__topic">
{roomTopic && (
<Text variant="b2">{twemojify(roomTopic, undefined, true)}</Text>
)}
</div>
</div>
<div class="room-header__right">
{mx.isRoomEncrypted(roomId) === false && (
<IconButton
onClick={() => toggleRoomSettings(tabText.SEARCH)}
tooltip="Search"
src={SearchIC}
/>
)}
<IconButton
className="room-header__drawer-btn"
onClick={togglePeopleDrawer}
tooltip="People"
src={UserIC}
/>
<IconButton
className="room-header__members-btn"
onClick={() => toggleRoomSettings(tabText.MEMBERS)}
tooltip="Members"
src={UserIC}
/>
<IconButton
onClick={openRoomOptions}
tooltip="Options"
src={VerticalMenuIC}
/>
</div>
</Header>
);
}
RoomViewHeader.propTypes = {
roomId: PropTypes.string.isRequired,
};
export default RoomViewHeader;

View file

@ -7,7 +7,12 @@
"esModuleInterop": true,
"moduleResolution": "Node",
"outDir": "dist",
"skipLibCheck": true
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@": ["src/*"]
}
},
"exclude": ["node_modules", "dist"],
"include": ["src"]

View file

@ -5,6 +5,7 @@ import { viteStaticCopy } from "vite-plugin-static-copy";
import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
import inject from "@rollup/plugin-inject";
import { svgLoader } from "./viteSvgLoader";
import path from "path";
const copyFiles = {
targets: [
@ -35,6 +36,11 @@ export default defineConfig({
port: 8080,
host: true,
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
plugins: [viteStaticCopy(copyFiles), svgLoader(), wasm(), react()],
optimizeDeps: {
esbuildOptions: {