Display application icon
This commit is contained in:
16
matrixgw_frontend/package-lock.json
generated
16
matrixgw_frontend/package-lock.json
generated
@@ -24,6 +24,7 @@
|
|||||||
"qrcode.react": "^4.2.0",
|
"qrcode.react": "^4.2.0",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
|
"react-favicon": "^2.0.7",
|
||||||
"react-json-view-lite": "^2.5.0",
|
"react-json-view-lite": "^2.5.0",
|
||||||
"react-router": "^7.9.5"
|
"react-router": "^7.9.5"
|
||||||
},
|
},
|
||||||
@@ -3691,6 +3692,21 @@
|
|||||||
"react": "^19.2.0"
|
"react": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-favicon": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-favicon/-/react-favicon-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-Vqjk8VHnOu7vl7JnP13nPJ05DyFGObF655xFkbTUIbF4vqLx1Slbc56Hrbzg1leROAKHzElm3u4KUzaXO46A6A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"prop-types": "^15.8.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "19.2.0",
|
"version": "19.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"qrcode.react": "^4.2.0",
|
"qrcode.react": "^4.2.0",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
|
"react-favicon": "^2.0.7",
|
||||||
"react-json-view-lite": "^2.5.0",
|
"react-json-view-lite": "^2.5.0",
|
||||||
"react-router": "^7.9.5"
|
"react-router": "^7.9.5"
|
||||||
},
|
},
|
||||||
|
|||||||
26
matrixgw_frontend/src/widgets/messages/AppIconModifier.tsx
Normal file
26
matrixgw_frontend/src/widgets/messages/AppIconModifier.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import Favicon from "react-favicon";
|
||||||
|
|
||||||
|
// Taken from https://github.com/element-hq/element-web/blob/0577e245dac944bd85eea07b93a9762a93062f62/src/favicon.ts
|
||||||
|
function getInitialFavicon(): HTMLLinkElement[] {
|
||||||
|
const icons: HTMLLinkElement[] = [];
|
||||||
|
const links = window.document
|
||||||
|
.getElementsByTagName("head")[0]
|
||||||
|
.getElementsByTagName("link");
|
||||||
|
for (const link of links) {
|
||||||
|
if (
|
||||||
|
link.hasAttribute("rel") &&
|
||||||
|
/(^|\s)icon(\s|$)/i.test(link.getAttribute("rel")!)
|
||||||
|
) {
|
||||||
|
icons.push(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
let iconPath = getInitialFavicon()[0].getAttribute("href")!;
|
||||||
|
|
||||||
|
export function AppIconModifier(p: {
|
||||||
|
numberUnread: number;
|
||||||
|
}): React.ReactElement {
|
||||||
|
return <Favicon url={iconPath} alertCount={p.numberUnread} />;
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import type { WsMessage } from "../../api/WsApi";
|
|||||||
import { RoomEventsManager } from "../../utils/RoomEventsManager";
|
import { RoomEventsManager } from "../../utils/RoomEventsManager";
|
||||||
import { AsyncWidget } from "../AsyncWidget";
|
import { AsyncWidget } from "../AsyncWidget";
|
||||||
import { useUserInfo } from "../dashboard/BaseAuthenticatedPage";
|
import { useUserInfo } from "../dashboard/BaseAuthenticatedPage";
|
||||||
|
import { AppIconModifier } from "./AppIconModifier";
|
||||||
import { MatrixWS } from "./MatrixWS";
|
import { MatrixWS } from "./MatrixWS";
|
||||||
import { RoomSelector } from "./RoomSelector";
|
import { RoomSelector } from "./RoomSelector";
|
||||||
import { RoomWidget } from "./RoomWidget";
|
import { RoomWidget } from "./RoomWidget";
|
||||||
@@ -70,6 +71,11 @@ function _MainMessageWidget(p: {
|
|||||||
);
|
);
|
||||||
}, [space, p.rooms]);
|
}, [space, p.rooms]);
|
||||||
|
|
||||||
|
const unreadRooms = React.useMemo(
|
||||||
|
() => p.rooms.filter((r) => r.number_unread_messages > 0).length,
|
||||||
|
[p.rooms]
|
||||||
|
);
|
||||||
|
|
||||||
const [_refreshCount, setRefreshCount] = React.useState(0);
|
const [_refreshCount, setRefreshCount] = React.useState(0);
|
||||||
const [roomMgr, setRoomMgr] = React.useState<undefined | RoomEventsManager>();
|
const [roomMgr, setRoomMgr] = React.useState<undefined | RoomEventsManager>();
|
||||||
|
|
||||||
@@ -117,6 +123,9 @@ function _MainMessageWidget(p: {
|
|||||||
<MatrixWS onMessage={handleWsEvent} />
|
<MatrixWS onMessage={handleWsEvent} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/** Application icon modifier */}
|
||||||
|
<AppIconModifier numberUnread={unreadRooms} />
|
||||||
|
|
||||||
{/* Space selector */}
|
{/* Space selector */}
|
||||||
<SpaceSelector {...p} selectedSpace={space} onChange={setSpace} />
|
<SpaceSelector {...p} selectedSpace={space} onChange={setSpace} />
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user