forked from Mirrors/gomuks
web/timeline: lazy-load images and avatars
This commit is contained in:
parent
67c9060e85
commit
c52c9029a7
3 changed files with 13 additions and 12 deletions
|
@ -15,12 +15,12 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import { RoomStateStore } from "../../api/statestore.ts"
|
import { RoomStateStore } from "../../api/statestore.ts"
|
||||||
|
import { getMediaURL } from "../../api/media.ts"
|
||||||
import { DBEvent, MemberEventContent } from "../../api/types"
|
import { DBEvent, MemberEventContent } from "../../api/types"
|
||||||
import HiddenEvent from "./content/HiddenEvent.tsx"
|
import HiddenEvent from "./content/HiddenEvent.tsx"
|
||||||
import MessageBody from "./content/MessageBody.tsx"
|
import MessageBody from "./content/MessageBody.tsx"
|
||||||
import { EventContentProps } from "./content/props.ts"
|
import { EventContentProps } from "./content/props.ts"
|
||||||
import "./TimelineEvent.css"
|
import "./TimelineEvent.css"
|
||||||
import { getMediaURL } from "../../api/media.ts"
|
|
||||||
|
|
||||||
export interface TimelineEventProps {
|
export interface TimelineEventProps {
|
||||||
room: RoomStateStore
|
room: RoomStateStore
|
||||||
|
@ -51,7 +51,7 @@ const TimelineEvent = ({ room, eventRowID }: TimelineEventProps) => {
|
||||||
// }
|
// }
|
||||||
return <div className="timeline-event">
|
return <div className="timeline-event">
|
||||||
<div className="sender-avatar">
|
<div className="sender-avatar">
|
||||||
<img src={getMediaURL(memberEvtContent?.avatar_url)} alt="" />
|
<img loading="lazy" src={getMediaURL(memberEvtContent?.avatar_url)} alt="" />
|
||||||
</div>
|
</div>
|
||||||
<div className="sender-and-content">
|
<div className="sender-and-content">
|
||||||
<div className="event-sender-and-time">
|
<div className="event-sender-and-time">
|
||||||
|
|
|
@ -79,15 +79,15 @@ const MessageBody = ({ event }: EventContentProps) => {
|
||||||
case "m.image": {
|
case "m.image": {
|
||||||
const openLightbox = use(LightboxContext)
|
const openLightbox = use(LightboxContext)
|
||||||
const style = calculateMediaSize(content.info?.w, content.info?.h)
|
const style = calculateMediaSize(content.info?.w, content.info?.h)
|
||||||
if (content.url) {
|
return <div className="media-container" style={style.container}>
|
||||||
return <div className="media-container" style={style.container}>
|
<img
|
||||||
<img style={style.media} src={getMediaURL(content.url)} alt={content.body} onClick={openLightbox}/>
|
loading="lazy"
|
||||||
</div>
|
style={style.media}
|
||||||
} else if (content.file) {
|
src={getMediaURL(content.url ?? content.file?.url)}
|
||||||
return <div className="media-container" style={style.container}>
|
alt={content.body}
|
||||||
<img style={style.media} src={getMediaURL(content.file.url)} alt={content.body} onClick={openLightbox}/>
|
onClick={openLightbox}
|
||||||
</div>
|
/>
|
||||||
}
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <code>{`{ "type": "${event.type}" }`}</code>
|
return <code>{`{ "type": "${event.type}" }`}</code>
|
||||||
|
|
|
@ -85,6 +85,7 @@ export const transformTags: NonNullable<sanitizeHtml.IOptions["transformTags"]>
|
||||||
}
|
}
|
||||||
|
|
||||||
attribs.src = getMediaURL(src)!
|
attribs.src = getMediaURL(src)!
|
||||||
|
attribs.loading = "lazy"
|
||||||
return { tagName, attribs }
|
return { tagName, attribs }
|
||||||
},
|
},
|
||||||
"code": function(tagName: string, attribs: sanitizeHtml.Attributes) {
|
"code": function(tagName: string, attribs: sanitizeHtml.Attributes) {
|
||||||
|
@ -188,7 +189,7 @@ export const sanitizeHtmlParams: sanitizeHtml.IOptions = {
|
||||||
// eslint-disable-next-line id-length
|
// eslint-disable-next-line id-length
|
||||||
a: ["href", "name", "target", "rel"], // remote target: custom to matrix
|
a: ["href", "name", "target", "rel"], // remote target: custom to matrix
|
||||||
// img tags also accept width/height, we just map those to max-width & max-height during transformation
|
// img tags also accept width/height, we just map those to max-width & max-height during transformation
|
||||||
img: ["src", "alt", "title", "style", "data-mx-emoticon"],
|
img: ["src", "alt", "title", "style", "loading", "data-mx-emoticon"],
|
||||||
ol: ["start"],
|
ol: ["start"],
|
||||||
code: ["class"], // We don't actually allow all classes, we filter them in transformTags
|
code: ["class"], // We don't actually allow all classes, we filter them in transformTags
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue