Skip to content

Commit

Permalink
Add FetchedImage to use IPC to load image dynamically
Browse files Browse the repository at this point in the history
  • Loading branch information
sirbrillig committed Dec 17, 2024
1 parent 3b50e41 commit 9bc9b0f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
57 changes: 57 additions & 0 deletions src/renderer/components/fetched-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import { AccountInfo } from '../../shared-types';

export function FetchedImage({
src,
account,
}: {
src: string;
account: AccountInfo;
}) {
const [imgSrc, setImgSrc] = React.useState<string | undefined>();
const isFetched = React.useRef<boolean>(false);

const fetchImage = React.useCallback(async () => {
const bytes = await window.electronApi.getRawImage(src, account);
if ('error' in bytes) {
console.error(`Error loading image ${src}`, bytes.error);
return;
}
const blob = new Blob(bytes);
const imageObjectURL = URL.createObjectURL(blob);
setImgSrc(imageObjectURL);
}, [src]);

React.useEffect(() => {
return () => {
// Make sure to reset isFetched if the component is unmounted.
isFetched.current = false;
};
}, []);

React.useEffect(() => {
if (isFetched.current) {
return;
}
isFetched.current = true;
fetchImage();
}, [fetchImage]);

if (!imgSrc) {
return <PlaceholderComponent />;
}
return <img src={imgSrc} />;
}

function PlaceholderComponent() {
return React.createElement(
'svg',
{ width: '33', height: '33' },
React.createElement('circle', {
cx: '16',
cy: '16',
r: '15',
fill: 'orange',
})
);
}
14 changes: 12 additions & 2 deletions src/renderer/components/notification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react';
import Gridicon from 'gridicons';
import debugFactory from 'debug';
import { formatDistanceToNow } from 'date-fns';
import EnsuredImage from './ensured-image';
import MuteIcon from './mute-icon';
import {
Note,
Expand All @@ -11,7 +10,11 @@ import {
MarkUnread,
MuteRepo,
UnmuteRepo,
AppReduxState,
} from '../types';
import { FetchedImage } from './fetched-image';
import { useSelector } from 'react-redux';
import EnsuredImage from './ensured-image';

const debug = debugFactory('gitnews-menubar');

Expand Down Expand Up @@ -47,6 +50,9 @@ export default function Notification({
const isUnread =
note.unread === true ? true : note.gitnewsMarkedUnread === true;

const accounts = useSelector((state: AppReduxState) => state.accounts);
const account = accounts.find(({ id }) => id === note.gitnewsAccountId);

const onClick = () => {
debug('clicked on notification', note);
setMuteRequested(false);
Expand Down Expand Up @@ -134,7 +140,11 @@ export default function Notification({
<div className="notification__image">
{isUnread && <span className="notification__new-dot" />}
{isMuted && <MuteIcon className="mute-icon" />}
<EnsuredImage src={avatarSrc} />
{account ? (
<FetchedImage src={avatarSrc} account={account} />
) : (
<EnsuredImage src={avatarSrc} />
)}
</div>
<div className="notification__body">
<div className="notification__repo">
Expand Down

0 comments on commit 9bc9b0f

Please sign in to comment.