Compare commits

..

No commits in common. "1cc897a7a3b27629a159d6bacea334bcb112c7f9" and "6f68a700cea3399fc7a3a161e2eee98cbc45b5ca" have entirely different histories.

8 changed files with 23 additions and 52 deletions

View File

@ -84,7 +84,6 @@ export default gql`
hideIsContributor: Boolean! hideIsContributor: Boolean!
hideWalletBalance: Boolean! hideWalletBalance: Boolean!
imgproxyOnly: Boolean! imgproxyOnly: Boolean!
showImagesAndVideos: Boolean!
nostrCrossposting: Boolean! nostrCrossposting: Boolean!
nostrPubkey: String nostrPubkey: String
nostrRelays: [String!] nostrRelays: [String!]
@ -156,7 +155,6 @@ export default gql`
hideIsContributor: Boolean! hideIsContributor: Boolean!
hideWalletBalance: Boolean! hideWalletBalance: Boolean!
imgproxyOnly: Boolean! imgproxyOnly: Boolean!
showImagesAndVideos: Boolean!
nostrCrossposting: Boolean! nostrCrossposting: Boolean!
nostrPubkey: String nostrPubkey: String
nostrRelays: [String!] nostrRelays: [String!]

View File

@ -19,25 +19,13 @@ export function decodeOriginalUrl (imgproxyUrl) {
return originalUrl return originalUrl
} }
function LinkRaw ({ href, children, src, rel, onClick, ...props }) { function ImageOriginal ({ src, topLevel, rel, tab, children, onClick, ...props }) {
const isRawURL = /^https?:\/\//.test(children?.[0])
return (
// eslint-disable-next-line
<a
target='_blank'
rel={rel ?? UNKNOWN_LINK_REL}
href={src}
>{isRawURL || !children ? src : children}
</a>
)
}
function ImageOriginal ({ src, topLevel, tab, onClick, ...props }) {
const me = useMe() const me = useMe()
const [showImage, setShowImage] = useState(false) const [showImage, setShowImage] = useState(false)
const [showVideo, setShowVideo] = useState(false) const [showVideo, setShowVideo] = useState(false)
useEffect(() => { useEffect(() => {
if (me?.privates?.imgproxyOnly && tab !== 'preview') return
// make sure it's not a false negative by trying to load URL as <img> // make sure it's not a false negative by trying to load URL as <img>
const img = new window.Image() const img = new window.Image()
img.onload = () => setShowImage(true) img.onload = () => setShowImage(true)
@ -54,9 +42,7 @@ function ImageOriginal ({ src, topLevel, tab, onClick, ...props }) {
} }
}, [src, showImage]) }, [src, showImage])
const showMedia = (tab === 'preview' || (me?.privates?.showImagesAndVideos !== false && !me?.privates?.imgproxyOnly)) if (showImage) {
if (showImage && showMedia) {
return ( return (
<img <img
className={topLevel ? styles.topLevel : undefined} className={topLevel ? styles.topLevel : undefined}
@ -65,14 +51,23 @@ function ImageOriginal ({ src, topLevel, tab, onClick, ...props }) {
onError={() => setShowImage(false)} onError={() => setShowImage(false)}
/> />
) )
} else if (showVideo && showMedia) { } else if (showVideo) {
return <video src={src} controls /> return <video src={src} controls />
} else { } else {
// user is not okay with loading original url automatically or there was an error loading the image // user is not okay with loading original url automatically or there was an error loading the image
// If element parsed by markdown is a raw URL, we use src as the text to not mislead users. // If element parsed by markdown is a raw URL, we use src as the text to not mislead users.
// This will not be the case if [text](url) format is used. Then we will show what was chosen as text. // This will not be the case if [text](url) format is used. Then we will show what was chosen as text.
return <LinkRaw src={src} {...props} /> const isRawURL = /^https?:\/\//.test(children?.[0])
return (
// eslint-disable-next-line
<a
target='_blank'
rel={rel ?? UNKNOWN_LINK_REL}
href={src}
>{isRawURL || !children ? src : children}
</a>
)
} }
} }
@ -143,7 +138,6 @@ const Image = memo(({ className, src, srcSet, sizes, width, height, onClick, onE
export default function ZoomableImage ({ src, srcSet, ...props }) { export default function ZoomableImage ({ src, srcSet, ...props }) {
const showModal = useShowModal() const showModal = useShowModal()
const me = useMe()
// if `srcSet` is falsy, it means the image was not processed by worker yet // if `srcSet` is falsy, it means the image was not processed by worker yet
const [trustedDomain, setTrustedDomain] = useState(!!srcSet || IMGPROXY_URL_REGEXP.test(src) || MEDIA_DOMAIN_REGEXP.test(src)) const [trustedDomain, setTrustedDomain] = useState(!!srcSet || IMGPROXY_URL_REGEXP.test(src) || MEDIA_DOMAIN_REGEXP.test(src))
@ -177,16 +171,12 @@ export default function ZoomableImage ({ src, srcSet, ...props }) {
if (!src) return null if (!src) return null
if (trustedDomain) { if (trustedDomain) {
if (props.tab === 'preview' || !me || me.privates.showImagesAndVideos) {
return ( return (
<TrustedImage <TrustedImage
src={src} srcSet={srcSet} src={src} srcSet={srcSet}
onClick={handleClick} onError={handleError} {...props} onClick={handleClick} onError={handleError} {...props}
/> />
) )
} else {
return <LinkRaw src={src} onClick={handleClick} {...props} />
}
} }
return <ImageOriginal src={originalUrl} onClick={handleClick} {...props} /> return <ImageOriginal src={originalUrl} onClick={handleClick} {...props} />

View File

@ -135,13 +135,13 @@
max-width: 100%; max-width: 100%;
height: auto; height: auto;
max-height: 25vh; max-height: 25vh;
min-width: 50%;
aspect-ratio: var(--aspect-ratio); aspect-ratio: var(--aspect-ratio);
} }
.text img { .text img {
cursor: zoom-in; cursor: zoom-in;
object-fit: contain; object-fit: contain;
min-width: 50%;
object-position: left top; object-position: left top;
} }

View File

@ -26,7 +26,6 @@ export const ME = gql`
hideWalletBalance hideWalletBalance
hideWelcomeBanner hideWelcomeBanner
imgproxyOnly imgproxyOnly
showImagesAndVideos
lastCheckedJobs lastCheckedJobs
nostrCrossposting nostrCrossposting
noteAllDescendants noteAllDescendants
@ -99,7 +98,6 @@ export const SETTINGS_FIELDS = gql`
hideTwitter hideTwitter
hideIsContributor hideIsContributor
imgproxyOnly imgproxyOnly
showImagesAndVideos
hideWalletBalance hideWalletBalance
diagnostics diagnostics
noReferralLinks noReferralLinks

View File

@ -87,7 +87,7 @@ export function middleware (request) {
"font-src 'self' a.stacker.news", "font-src 'self' a.stacker.news",
// we want to load images from everywhere but we can limit to HTTPS at least // we want to load images from everywhere but we can limit to HTTPS at least
"img-src 'self' a.stacker.news m.stacker.news https: data: blob:" + devSrc, "img-src 'self' a.stacker.news m.stacker.news https: data: blob:" + devSrc,
"media-src 'self' a.stacker.news m.stacker.news https:" + devSrc, "media-src 'self' a.stacker.news m.stacker.news" + devSrc,
// Using nonces and strict-dynamic deploys a strict CSP. // Using nonces and strict-dynamic deploys a strict CSP.
// see https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html#strict-policy. // see https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html#strict-policy.
// Old browsers will ignore nonce and strict-dynamic and fallback to host-based matching and unsafe-inline // Old browsers will ignore nonce and strict-dynamic and fallback to host-based matching and unsafe-inline

View File

@ -116,7 +116,7 @@ export default function Settings ({ ssrData }) {
tipRandomMin: settings?.tipRandomMin || 1, tipRandomMin: settings?.tipRandomMin || 1,
tipRandomMax: settings?.tipRandomMax || 10, tipRandomMax: settings?.tipRandomMax || 10,
turboTipping: settings?.turboTipping, turboTipping: settings?.turboTipping,
disableFreebies: settings?.disableFreebies || undefined, disableFreebies: settings?.disableFreebies,
zapUndos: settings?.zapUndos || (settings?.tipDefault ? 100 * settings.tipDefault : 2100), zapUndos: settings?.zapUndos || (settings?.tipDefault ? 100 * settings.tipDefault : 2100),
zapUndosEnabled: settings?.zapUndos !== null, zapUndosEnabled: settings?.zapUndos !== null,
fiatCurrency: settings?.fiatCurrency || 'USD', fiatCurrency: settings?.fiatCurrency || 'USD',
@ -140,7 +140,6 @@ export default function Settings ({ ssrData }) {
hideNostr: settings?.hideNostr, hideNostr: settings?.hideNostr,
hideTwitter: settings?.hideTwitter, hideTwitter: settings?.hideTwitter,
imgproxyOnly: settings?.imgproxyOnly, imgproxyOnly: settings?.imgproxyOnly,
showImagesAndVideos: settings?.showImagesAndVideos,
wildWestMode: settings?.wildWestMode, wildWestMode: settings?.wildWestMode,
satsFilter: settings?.satsFilter, satsFilter: settings?.satsFilter,
nsfwMode: settings?.nsfwMode, nsfwMode: settings?.nsfwMode,
@ -509,17 +508,6 @@ export default function Settings ({ ssrData }) {
required required
append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>} append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>}
/> />
<Checkbox
label={
<div className='d-flex align-items-center'>show images and video
<Info>
<p>disable to show images and videos as links instead of embedding them</p>
</Info>
</div>
}
name='showImagesAndVideos'
groupClassName='mb-0'
/>
<Checkbox <Checkbox
label={ label={
<div className='d-flex align-items-center'>wild west mode <div className='d-flex align-items-center'>wild west mode

View File

@ -1,2 +0,0 @@
-- AlterTable
ALTER TABLE "users" ADD COLUMN "showImagesAndVideos" BOOLEAN NOT NULL DEFAULT true;

View File

@ -63,7 +63,6 @@ model User {
turboTipping Boolean @default(false) turboTipping Boolean @default(false)
zapUndos Int? zapUndos Int?
imgproxyOnly Boolean @default(false) imgproxyOnly Boolean @default(false)
showImagesAndVideos Boolean @default(true)
hideWalletBalance Boolean @default(false) hideWalletBalance Boolean @default(false)
disableFreebies Boolean? disableFreebies Boolean?
referrerId Int? referrerId Int?