Embed resources

This commit is contained in:
Philipp Heckel 2022-03-09 15:58:21 -05:00
parent 8c8a1685b2
commit 04ee6b8be2
28 changed files with 60 additions and 57 deletions

27
web/.gitignore vendored
View file

@ -1,27 +0,0 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# IDEs and editors
/.idea
/.vscode
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View file

@ -15,7 +15,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="#317f6f"> <meta name="apple-mobile-web-app-status-bar-style" content="#317f6f">
<!-- Favicon, see favicon.io --> <!-- Favicon, see favicon.io -->
<link rel="icon" type="image/png" href="%PUBLIC_URL%/static/img/favicon.png"> <link rel="icon" type="image/png" href="static/img/favicon.png">
<!-- Previews in Google, Slack, WhatsApp, etc. --> <!-- Previews in Google, Slack, WhatsApp, etc. -->
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
@ -30,7 +30,7 @@
<meta name="robots" content="noindex, nofollow" /> <meta name="robots" content="noindex, nofollow" />
<!-- Fonts --> <!-- Fonts -->
<link rel="stylesheet" href="%PUBLIC_URL%/static/css/fonts.css" type="text/css"> <link rel="stylesheet" href="static/css/fonts.css" type="text/css">
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View file

@ -1,6 +1,7 @@
import {formatMessage, formatTitleWithDefault, openUrl, playSound, topicShortUrl} from "./utils"; import {formatMessage, formatTitleWithDefault, openUrl, playSound, topicShortUrl} from "./utils";
import prefs from "./Prefs"; import prefs from "./Prefs";
import subscriptionManager from "./SubscriptionManager"; import subscriptionManager from "./SubscriptionManager";
import logo from "../img/ntfy.png";
class Notifier { class Notifier {
async notify(subscriptionId, notification, onClickFallback) { async notify(subscriptionId, notification, onClickFallback) {
@ -17,7 +18,7 @@ class Notifier {
console.log(`[Notifier, ${shortUrl}] Displaying notification ${notification.id}: ${message}`); console.log(`[Notifier, ${shortUrl}] Displaying notification ${notification.id}: ${message}`);
const n = new Notification(title, { const n = new Notification(title, {
body: message, body: message,
icon: '/static/img/favicon.png' icon: logo
}); });
if (notification.click) { if (notification.click) {
n.onclick = (e) => openUrl(notification.click); n.onclick = (e) => openUrl(notification.click);
@ -32,7 +33,6 @@ class Notifier {
await playSound(sound); await playSound(sound);
} catch (e) { } catch (e) {
console.log(`[Notifier, ${shortUrl}] Error playing audio`, e); console.log(`[Notifier, ${shortUrl}] Error playing audio`, e);
// FIXME show no sound allowed popup
} }
} }
} }

View file

@ -7,7 +7,7 @@ class Prefs {
async sound() { async sound() {
const sound = await db.prefs.get('sound'); const sound = await db.prefs.get('sound');
return (sound) ? sound.value : "mixkit-correct-answer-tone"; return (sound) ? sound.value : "ding";
} }
async setMinPriority(minPriority) { async setMinPriority(minPriority) {

View file

@ -1,4 +1,11 @@
import {rawEmojis} from "./emojis"; import {rawEmojis} from "./emojis";
import beep from "../sounds/beep.mp3";
import juntos from "../sounds/juntos.mp3";
import pristine from "../sounds/pristine.mp3";
import ding from "../sounds/ding.mp3";
import dadum from "../sounds/dadum.mp3";
import pop from "../sounds/pop.mp3";
import popSwoosh from "../sounds/pop-swoosh.mp3";
export const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`; export const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`;
export const topicUrlWs = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/ws` export const topicUrlWs = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/ws`
@ -34,7 +41,6 @@ const toEmojis = (tags) => {
else return tags.filter(tag => tag in emojis).map(tag => emojis[tag]); else return tags.filter(tag => tag in emojis).map(tag => emojis[tag]);
} }
export const formatTitleWithDefault = (m, fallback) => { export const formatTitleWithDefault = (m, fallback) => {
if (m.title) { if (m.title) {
return formatTitle(m); return formatTitle(m);
@ -123,8 +129,18 @@ export const subscriptionRoute = (subscription) => {
return `/${subscription.topic}`; return `/${subscription.topic}`;
} }
export const sounds = {
"beep": beep,
"juntos": juntos,
"pristine": pristine,
"ding": ding,
"dadum": dadum,
"pop": pop,
"pop-swoosh": popSwoosh
};
export const playSound = async (sound) => { export const playSound = async (sound) => {
const audio = new Audio(`/static/sounds/${sound}.mp3`); const audio = new Audio(sounds[sound]);
return audio.play(); return audio.play();
}; };

View file

@ -20,6 +20,7 @@ import NotificationsIcon from '@mui/icons-material/Notifications';
import NotificationsOffIcon from '@mui/icons-material/NotificationsOff'; import NotificationsOffIcon from '@mui/icons-material/NotificationsOff';
import api from "../app/Api"; import api from "../app/Api";
import subscriptionManager from "../app/SubscriptionManager"; import subscriptionManager from "../app/SubscriptionManager";
import logo from "../img/ntfy.svg"
const ActionBar = (props) => { const ActionBar = (props) => {
const location = useLocation(); const location = useLocation();
@ -44,7 +45,7 @@ const ActionBar = (props) => {
> >
<MenuIcon /> <MenuIcon />
</IconButton> </IconButton>
<Box component="img" src="/static/img/ntfy.svg" sx={{ <Box component="img" src={logo} sx={{
display: { xs: 'none', sm: 'block' }, display: { xs: 'none', sm: 'block' },
marginRight: '10px', marginRight: '10px',
height: '28px' height: '28px'
@ -152,11 +153,7 @@ const SettingsIcons = (props) => {
> >
<Paper> <Paper>
<ClickAwayListener onClickAway={handleClose}> <ClickAwayListener onClickAway={handleClose}>
<MenuList <MenuList autoFocusItem={open} onKeyDown={handleListKeyDown}>
autoFocusItem={open}
id="composition-menu"
onKeyDown={handleListKeyDown}
>
<MenuItem onClick={handleSendTestMessage}>Send test notification</MenuItem> <MenuItem onClick={handleSendTestMessage}>Send test notification</MenuItem>
<MenuItem onClick={handleClearAll}>Clear all notifications</MenuItem> <MenuItem onClick={handleClearAll}>Clear all notifications</MenuItem>
<MenuItem onClick={handleUnsubscribe}>Unsubscribe</MenuItem> <MenuItem onClick={handleUnsubscribe}>Unsubscribe</MenuItem>

View file

@ -21,6 +21,16 @@ import Box from "@mui/material/Box";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import subscriptionManager from "../app/SubscriptionManager"; import subscriptionManager from "../app/SubscriptionManager";
import InfiniteScroll from "react-infinite-scroll-component"; import InfiniteScroll from "react-infinite-scroll-component";
import fileApp from "../img/file-app.svg";
import fileAudio from "../img/file-audio.svg";
import fileDocument from "../img/file-document.svg";
import fileImage from "../img/file-image.svg";
import fileVideo from "../img/file-video.svg";
import priority1 from "../img/priority-1.svg";
import priority2 from "../img/priority-2.svg";
import priority4 from "../img/priority-4.svg";
import priority5 from "../img/priority-5.svg";
import logoOutline from "../img/ntfy-outline.svg";
const Notifications = (props) => { const Notifications = (props) => {
if (props.mode === "all") { if (props.mode === "all") {
@ -113,7 +123,7 @@ const NotificationItem = (props) => {
{date} {date}
{[1,2,4,5].includes(notification.priority) && {[1,2,4,5].includes(notification.priority) &&
<img <img
src={`/static/img/priority-${notification.priority}.svg`} src={priorityFiles[notification.priority]}
alt={`Priority ${notification.priority}`} alt={`Priority ${notification.priority}`}
style={{ verticalAlign: 'bottom' }} style={{ verticalAlign: 'bottom' }}
/>} />}
@ -139,6 +149,13 @@ const NotificationItem = (props) => {
); );
} }
const priorityFiles = {
1: priority1,
2: priority2,
4: priority4,
5: priority5
};
const Attachment = (props) => { const Attachment = (props) => {
const attachment = props.attachment; const attachment = props.attachment;
const expired = attachment.expires && attachment.expires < Date.now()/1000; const expired = attachment.expires && attachment.expires < Date.now()/1000;
@ -218,7 +235,7 @@ const Image = (props) => {
<> <>
<Box <Box
component="img" component="img"
src={`${props.attachment.url}`} src={props.attachment.url}
loading="lazy" loading="lazy"
onClick={() => setOpen(true)} onClick={() => setOpen(true)}
sx={{ sx={{
@ -239,7 +256,7 @@ const Image = (props) => {
<Fade in={open}> <Fade in={open}>
<Box <Box
component="img" component="img"
src={`${props.attachment.url}`} src={props.attachment.url}
loading="lazy" loading="lazy"
sx={{ sx={{
maxWidth: 1, maxWidth: 1,
@ -261,22 +278,22 @@ const Icon = (props) => {
const type = props.type; const type = props.type;
let imageFile; let imageFile;
if (!type) { if (!type) {
imageFile = 'file-document.svg'; imageFile = fileDocument;
} else if (type.startsWith('image/')) { } else if (type.startsWith('image/')) {
imageFile = 'file-image.svg'; imageFile = fileImage;
} else if (type.startsWith('video/')) { } else if (type.startsWith('video/')) {
imageFile = 'file-video.svg'; imageFile = fileVideo;
} else if (type.startsWith('audio/')) { } else if (type.startsWith('audio/')) {
imageFile = 'file-audio.svg'; imageFile = fileAudio;
} else if (type === "application/vnd.android.package-archive") { } else if (type === "application/vnd.android.package-archive") {
imageFile = 'file-app.svg'; imageFile = fileApp;
} else { } else {
imageFile = 'file-document.svg'; imageFile = fileDocument;
} }
return ( return (
<Box <Box
component="img" component="img"
src={`/static/img/${imageFile}`} src={imageFile}
loading="lazy" loading="lazy"
sx={{ sx={{
width: '28px', width: '28px',
@ -291,7 +308,7 @@ const NoNotifications = (props) => {
return ( return (
<VerticallyCenteredContainer maxWidth="xs"> <VerticallyCenteredContainer maxWidth="xs">
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}> <Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
<img src="/static/img/ntfy-outline.svg" height="64" width="64" alt="No notifications"/><br /> <img src={logoOutline} height="64" width="64" alt="No notifications"/><br />
You haven't received any notifications for this topic yet. You haven't received any notifications for this topic yet.
</Typography> </Typography>
<Paragraph> <Paragraph>
@ -317,7 +334,7 @@ const NoNotificationsWithoutSubscription = (props) => {
return ( return (
<VerticallyCenteredContainer maxWidth="xs"> <VerticallyCenteredContainer maxWidth="xs">
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}> <Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
<img src="/static/img/ntfy-outline.svg" height="64" width="64" alt="No notifications"/><br /> <img src={logoOutline} height="64" width="64" alt="No notifications"/><br />
You haven't received any notifications. You haven't received any notifications.
</Typography> </Typography>
<Paragraph> <Paragraph>
@ -342,7 +359,7 @@ const NoSubscriptions = () => {
return ( return (
<VerticallyCenteredContainer maxWidth="xs"> <VerticallyCenteredContainer maxWidth="xs">
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}> <Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
<img src="/static/img/ntfy-outline.svg" height="64" width="64" alt="No topics"/><br /> <img src={logoOutline} height="64" width="64" alt="No topics"/><br />
It looks like you don't have any subscriptions yet. It looks like you don't have any subscriptions yet.
</Typography> </Typography>
<Paragraph> <Paragraph>

View file

@ -75,12 +75,12 @@ const Sound = () => {
<FormControl fullWidth variant="standard" sx={{ margin: 1 }}> <FormControl fullWidth variant="standard" sx={{ margin: 1 }}>
<Select value={sound} onChange={handleChange}> <Select value={sound} onChange={handleChange}>
<MenuItem value={"none"}>No sound</MenuItem> <MenuItem value={"none"}>No sound</MenuItem>
<MenuItem value={"mixkit-correct-answer-tone"}>Ding</MenuItem> <MenuItem value={"ding"}>Ding</MenuItem>
<MenuItem value={"juntos"}>Juntos</MenuItem> <MenuItem value={"juntos"}>Juntos</MenuItem>
<MenuItem value={"pristine"}>Pristine</MenuItem> <MenuItem value={"pristine"}>Pristine</MenuItem>
<MenuItem value={"mixkit-software-interface-start"}>Dadum</MenuItem> <MenuItem value={"dadum"}>Dadum</MenuItem>
<MenuItem value={"mixkit-message-pop-alert"}>Pop</MenuItem> <MenuItem value={"pop"}>Pop</MenuItem>
<MenuItem value={"mixkit-long-pop"}>Pop swoosh</MenuItem> <MenuItem value={"pop-swoosh"}>Pop swoosh</MenuItem>
<MenuItem value={"beep"}>Beep</MenuItem> <MenuItem value={"beep"}>Beep</MenuItem>
</Select> </Select>
</FormControl> </FormControl>

View file

Before

Width:  |  Height:  |  Size: 712 B

After

Width:  |  Height:  |  Size: 712 B

View file

Before

Width:  |  Height:  |  Size: 312 B

After

Width:  |  Height:  |  Size: 312 B

View file

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 272 B

View file

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 297 B

View file

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 297 B

View file

Before

Width:  |  Height:  |  Size: 7 KiB

After

Width:  |  Height:  |  Size: 7 KiB

BIN
web/src/img/ntfy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB