fallback for room avatar media repo (disabled by default)

master
f0x 6 years ago
parent e297ee04b6
commit 4197b2be4e

@ -21,7 +21,12 @@ let App = create({
displayName: "App", displayName: "App",
getInitialState: function() { getInitialState: function() {
return {rooms: []} return {
rooms: [],
options: {
fallbackMediaRepos: []
}
}
}, },
componentDidMount: function() { componentDidMount: function() {
@ -85,7 +90,7 @@ let App = create({
} }
return ( return (
<> <>
<Sidebar client={this.state.client} rooms={this.state.rooms} selectRoom={(roomId) => {this.setState({roomId: roomId})}}/> <Sidebar options={this.state.options} client={this.state.client} rooms={this.state.rooms} selectRoom={(roomId) => {this.setState({roomId: roomId})}}/>
<Chat client={this.state.client} roomId={this.state.roomId}/> <Chat client={this.state.client} roomId={this.state.roomId}/>
</> </>
) )

@ -14,7 +14,8 @@ let RoomListItem = create({
getInitialState: function() { getInitialState: function() {
let room = this.props.content let room = this.props.content
let client = this.props.properties.client let client = this.props.properties.client
let avatar = <svg id="avatar" ref={this.jdenticonRef}/> let jdenticon = <svg id="avatar" ref={this.jdenticonRef}/>
let avatarUrl
let roomState = room.getLiveTimeline().getState('f') let roomState = room.getLiveTimeline().getState('f')
let avatarState = roomState.getStateEvents('m.room.avatar') let avatarState = roomState.getStateEvents('m.room.avatar')
@ -22,14 +23,19 @@ let RoomListItem = create({
let event = avatarState[avatarState.length-1].event let event = avatarState[avatarState.length-1].event
let hs = client.baseUrl let hs = client.baseUrl
let media_mxc = event.content.url.slice(6) let media_mxc = event.content.url.slice(6)
let url = `${hs}/_matrix/media/v1/thumbnail/${media_mxc}?width=128&height=128&method=scale` let path = `/_matrix/media/v1/thumbnail/${media_mxc}?width=128&height=128&method=scale`
avatar = <img id="avatar" src={url}></img> avatarUrl = {
hs: hs,
path: path
}
} }
return { return {
filterName: room.name.toUpperCase(), filterName: room.name.toUpperCase(),
unread: Math.random() > 0.7, unread: Math.random() > 0.7,
avatar: avatar avatarUrl: avatarUrl,
jdenticon: jdenticon,
tries: 0
} }
}, },
@ -37,6 +43,24 @@ let RoomListItem = create({
jdenticon.update(ref, this.props.content.roomId) jdenticon.update(ref, this.props.content.roomId)
}, },
avatarFallback: function() {
// instead of falling back on jdenticon immediately, we can try
// a third-party homeserver's media repo
// this does come with trust issues, and is opt-in in settings
let fallbackMediaRepos = this.props.properties.options.fallbackMediaRepos
if (this.state.tries < fallbackMediaRepos.length) {
let avatarUrl = this.state.avatarUrl
avatarUrl.hs = fallbackMediaRepos[this.state.tries]
this.setState({
avatarUrl: avatarUrl,
tries: this.state.tries + 1
})
} else {
this.setState({avatarUrl: null, avatar: jdenticon})
}
},
setRef: function(ref) { setRef: function(ref) {
if (ref == null) { if (ref == null) {
return return
@ -57,7 +81,11 @@ let RoomListItem = create({
className += " unread" className += " unread"
} }
return <div className={className} ref={this.setRef}> return <div className={className} ref={this.setRef}>
{this.state.avatar} {this.state.avatarUrl ?
<img id="avatar" src={`${this.state.avatarUrl.hs}${this.state.avatarUrl.path}`} onError={this.avatarFallback}></img>
:
this.state.jdenticon
}
<span id="name">{this.props.content.name}</span> <span id="name">{this.props.content.name}</span>
</div> </div>
} }
@ -80,7 +108,7 @@ let Sidebar = create({
render: function() { render: function() {
return <div className="sidebar"> return <div className="sidebar">
<FilterList items={this.props.rooms} properties={{client: this.props.client}} element={RoomListItem} callback={(roomId) => {this.props.selectRoom(roomId)}}/> <FilterList items={this.props.rooms} properties={{client: this.props.client, options: this.props.options}} element={RoomListItem} callback={(roomId) => {this.props.selectRoom(roomId)}}/>
</div> </div>
} }
}) })

Loading…
Cancel
Save