Skip to content

Commit

Permalink
Hide sensitive image
Browse files Browse the repository at this point in the history
  • Loading branch information
h3poteto committed Nov 26, 2023
1 parent fcbca21 commit 8c30fe2
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 16 deletions.
3 changes: 2 additions & 1 deletion locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"closed": "Closed"
},
"show_more": "Show more",
"show_less": "Show less"
"show_less": "Show less",
"cw": "Media hidden"
}
},
"accounts": {
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
"typecheck": "tsc -p renderer --noEmit && tsc -p main --noEmit"
},
"dependencies": {
"blurhash": "^2.0.5",
"dayjs": "^1.11.10",
"dexie": "^3.2.4",
"electron-serve": "^1.1.0",
"electron-store": "^8.1.0",
"flowbite": "^2.0.0",
"flowbite-react": "^0.6.4",
"megalodon": "^9.1.1",
"react-blurhash": "^0.3.0",
"react-icons": "^4.11.0",
"react-intl": "^6.5.1",
"react-virtuoso": "^4.6.2",
Expand Down
14 changes: 10 additions & 4 deletions renderer/components/timelines/notification/Reaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Card from '../status/Card'
import Media from '../status/Media'
import { FaBarsProgress, FaHouse, FaPenToSquare, FaRetweet, FaStar } from 'react-icons/fa6'
import { useIntl } from 'react-intl'
import { useState } from 'react'

type Props = {
notification: Entity.Notification
Expand All @@ -17,6 +18,7 @@ type Props = {

export default function Reaction(props: Props) {
const status = props.notification.status
const [spoilered, setSpoilered] = useState(status.spoiler_text.length > 0)
const { formatMessage } = useIntl()

const refresh = async () => {
Expand Down Expand Up @@ -61,10 +63,14 @@ export default function Reaction(props: Props) {
<time dateTime={status.created_at}>{dayjs(status.created_at).format('YYYY-MM-DD HH:mm:ss')}</time>
</div>
</div>
<Body status={status} className="text-gray-600" />
{status.poll && <Poll poll={status.poll} onRefresh={refresh} client={props.client} className="text-gray-600" />}
{status.card && <Card card={status.card} />}
<Media media={status.media_attachments} />
<Body status={status} className="text-gray-600" spoilered={spoilered} setSpoilered={setSpoilered} />
{!spoilered && (
<>
{status.poll && <Poll poll={status.poll} onRefresh={refresh} client={props.client} className="text-gray-600" />}
{status.card && <Card card={status.card} />}
<Media media={status.media_attachments} sensitive={status.sensitive} />
</>
)}
</div>
</div>
</div>
Expand Down
64 changes: 54 additions & 10 deletions renderer/components/timelines/status/Media.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,64 @@
import { Entity } from 'megalodon'
import { useState } from 'react'
import { Blurhash } from 'react-blurhash'
import { FaEyeSlash } from 'react-icons/fa6'
import { FormattedMessage } from 'react-intl'

type Props = {
media: Array<Entity.Attachment>
sensitive: boolean
}
export default function Media(props: Props) {
const [sensitive, setSensitive] = useState(props.sensitive)

return (
<div className="mt-2 flex flex-wrap">
{props.media.map((media, key) => (
<img
key={key}
src={media.preview_url}
className="h-36 mr-2 mb-2 rounded-md max-w-full cursor-pointer"
alt={media.description}
title={media.description}
/>
))}
<div className="relative">
{sensitive ? (
<button className="absolute bg-gray-600 text-gray-200 top-1 left-1 p-1 rounded z-10" onClick={() => setSensitive(false)}>
<FormattedMessage id="timeline.status.cw" />
</button>
) : (
<button className="absolute bg-gray-600 text-gray-200 top-1 left-1 p-1 rounded z-10" onClick={() => setSensitive(true)}>
<FaEyeSlash />
</button>
)}

<div className="mt-2 flex flex-wrap gap-2">
{props.media.map((media, key) => (
<div key={key}>
<Attachment attachment={media} sensitive={sensitive} />
</div>
))}
</div>
</div>
)
}

type AttachmentProps = {
attachment: Entity.Attachment
sensitive: boolean
}

function Attachment(props: AttachmentProps) {
if (props.sensitive) {
return (
<Blurhash
hash={props.attachment.blurhash}
height={144}
width={144}
className="max-w-full rounded-md"
style={{ marginBottom: '2px' }}
/>
)
} else {
return (
<img
src={props.attachment.preview_url}
className="mb-2 max-w-full cursor-pointer"
style={{ width: '144px', height: '144px' }}
alt={props.attachment.description}
title={props.attachment.description}
/>
)
}
}
2 changes: 1 addition & 1 deletion renderer/components/timelines/status/Status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default function Status(props: Props) {
<>
{status.poll && <Poll poll={status.poll} onRefresh={onRefresh} client={props.client} />}
{status.card && <Card card={status.card} />}
<Media media={status.media_attachments} />
<Media media={status.media_attachments} sensitive={status.sensitive} />
</>
)}

Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,11 @@ bluebird@^3.5.5:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==

blurhash@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-2.0.5.tgz#efde729fc14a2f03571a6aa91b49cba80d1abe4b"
integrity sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==

boolean@^3.0.1:
version "3.2.0"
resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b"
Expand Down Expand Up @@ -3813,6 +3818,11 @@ randombytes@^2.1.0:
dependencies:
safe-buffer "^5.1.0"

react-blurhash@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/react-blurhash/-/react-blurhash-0.3.0.tgz#f125801d052644f74420c79b05981691d17c9705"
integrity sha512-XlKr4Ns1iYFRnk6DkAblNbAwN/bTJvxTVoxMvmTcURdc5oLoXZwqAF9N3LZUh/HT+QFlq5n6IS6VsDGsviYAiQ==

react-dom@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
Expand Down

0 comments on commit 8c30fe2

Please sign in to comment.