Skip to content

Commit

Permalink
Move thumbnail back to synced data
Browse files Browse the repository at this point in the history
  • Loading branch information
owi92 committed Nov 27, 2024
1 parent 8e50478 commit e373b7f
Show file tree
Hide file tree
Showing 15 changed files with 69 additions and 92 deletions.
6 changes: 3 additions & 3 deletions backend/src/api/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use crate::{
Context,
err::{self, ApiResult},
model::{
event::AuthorizedEvent,
series::Series,
realm::Realm,
event::AuthorizedEvent,
series::Series,
realm::Realm,
playlist::AuthorizedPlaylist,
search::{SearchEvent, SearchRealm, SearchSeries},
},
Expand Down
26 changes: 19 additions & 7 deletions backend/src/api/model/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub(crate) struct SyncedEventData {
updated: DateTime<Utc>,
start_time: Option<DateTime<Utc>>,
end_time: Option<DateTime<Utc>>,
thumbnail: Option<String>,

/// Duration in milliseconds
duration: i64,
Expand All @@ -59,7 +60,6 @@ pub(crate) struct SyncedEventData {
#[derive(Debug)]
pub(crate) struct AuthorizedEventData {
tracks: Vec<Track>,
thumbnail: Option<String>,
captions: Vec<Caption>,
segments: Vec<Segment>,
}
Expand Down Expand Up @@ -98,12 +98,12 @@ impl_from_db!(
start_time: row.start_time(),
end_time: row.end_time(),
duration: row.duration(),
thumbnail: row.thumbnail(),
}),
EventState::Waiting => None,
},
authorized_data: match row.state::<EventState>() {
EventState::Ready => Some(AuthorizedEventData {
thumbnail: row.thumbnail(),
tracks: row.tracks::<Vec<EventTrack>>().into_iter().map(Track::from).collect(),
captions: row.captions::<Vec<EventCaption>>()
.into_iter()
Expand Down Expand Up @@ -165,6 +165,9 @@ impl SyncedEventData {
fn duration(&self) -> f64 {
self.duration as f64
}
fn thumbnail(&self) -> Option<&str> {
self.thumbnail.as_deref()
}
}

/// Represents event data that is only accessible for users with read access
Expand All @@ -174,9 +177,6 @@ impl AuthorizedEventData {
fn tracks(&self) -> &[Track] {
&self.tracks
}
fn thumbnail(&self) -> Option<&str> {
self.thumbnail.as_deref()
}
fn captions(&self) -> &[Caption] {
&self.captions
}
Expand Down Expand Up @@ -231,8 +231,8 @@ impl AuthorizedEvent {
/// Returns the authorized event data if the user has read access or is authenticated for the event.
async fn authorized_data(
&self,
context: &Context,
user: Option<String>,
context: &Context,
user: Option<String>,
password: Option<String>,
) -> Option<&AuthorizedEventData> {
let sha1_matches = |input: &str, encoded: &str| {
Expand Down Expand Up @@ -319,6 +319,18 @@ impl AuthorizedEvent {
.get::<_, bool>(0)
.pipe(Ok)
}

async fn audio_only(&self, context: &Context) -> ApiResult<bool> {
let query = "select not exists ( \
select from events, unnest(tracks) as t \
where id = $1 and t.resolution is not null \
)";

context.db.query_one(&query, &[&self.key])
.await?
.get::<_, bool>(0)
.pipe(Ok)
}
}

#[derive(juniper::GraphQLUnion)]
Expand Down
2 changes: 1 addition & 1 deletion backend/src/api/model/search/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl SearchEvent {
title: src.title,
description: src.description,
creators: src.creators,
thumbnail: if user_can_read { src.thumbnail } else { None },
thumbnail: src.thumbnail,
duration: src.duration as f64,
created: src.created,
start_time: src.start_time,
Expand Down
1 change: 1 addition & 0 deletions frontend/src/routes/Embed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ const embedEventFragment = graphql`
startTime
endTime
duration
thumbnail
}
... VideoPageAuthorizedData
@arguments(eventUser: $eventUser, eventPassword: $eventPassword)
Expand Down
10 changes: 1 addition & 9 deletions frontend/src/routes/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ const query = graphql`
startTime
endTime
created
userIsAuthorized
hostRealms { path ancestorNames }
textMatches {
start
Expand Down Expand Up @@ -521,7 +520,6 @@ const SearchEvent: React.FC<EventItem> = ({
hostRealms,
textMatches,
matches,
userIsAuthorized,
}) => {
// TODO: decide what to do in the case of more than two host realms. Direct
// link should be avoided.
Expand All @@ -534,21 +532,15 @@ const SearchEvent: React.FC<EventItem> = ({
image: <Link to={link} tabIndex={-1}>
<Thumbnail
event={{
id,
title,
isLive,
created,
series: seriesId ? {
id: seriesId,
} : null,
audioOnly,
syncedData: {
duration,
startTime,
endTime,
},
authorizedData: !userIsAuthorized ? null : {
thumbnail,
audioOnly,
},
}}
/>
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/routes/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ const eventFragment = graphql`
duration
startTime
endTime
thumbnail
}
... VideoPageAuthorizedData
@arguments(eventUser: $eventUser, eventPassword: $eventPassword)
Expand All @@ -486,13 +487,12 @@ const authorizedDataFragment = graphql`
tracks { uri flavor mimetype resolution isMaster }
captions { uri lang }
segments { uri startTime }
thumbnail
}
}
`;

// Custom query to refetch authorized event data manually. Unfortunately, using
// the fragment here is not enough, we need to also selected `authorizedData`
// the fragment here is not enough, we need to also select `authorizedData`
// manually. Without that, we could not access that field below to check if the
// credentials were correct. Normally, adding `@relay(mask: false)` to the
// fragment should also fix that, but that does not work for some reason.
Expand All @@ -509,7 +509,7 @@ export const authorizedDataQuery = graphql`
@arguments(eventUser: $eventUser, eventPassword: $eventPassword)
...on AuthorizedEvent {
authorizedData(user: $eventUser, password: $eventPassword) {
thumbnail
__id
}
}
}
Expand Down Expand Up @@ -558,7 +558,7 @@ const VideoPage: React.FC<Props> = ({ eventRef, realmRef, playlistRef, basePath
"@type": "VideoObject",
name: event.title,
description: event.description ?? undefined,
thumbnailUrl: event.authorizedData?.thumbnail ?? undefined,
thumbnailUrl: event.syncedData?.thumbnail ?? undefined,
uploadDate: event.created,
duration: toIsoDuration(event.syncedData.duration),
...event.isLive && event.syncedData.startTime && event.syncedData.endTime && {
Expand Down
14 changes: 3 additions & 11 deletions frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export const EditVideoBlock: React.FC<EditVideoBlockProps> = ({ block: blockRef
created
isLive
creators
audioOnly
syncedData { duration startTime endTime }
authorizedData { thumbnail }
}
}
showTitle
Expand Down Expand Up @@ -152,6 +152,7 @@ const EventSelector: React.FC<EventSelectorProps> = ({ onChange, onBlur, default
duration
startTime
endTime
audioOnly
}
}
}
Expand Down Expand Up @@ -204,16 +205,7 @@ const formatOption = (event: Option, t: TFunction) => (
? <MovingTruck />
: <Thumbnail
css={{ width: 120, minWidth: 120 }}
event={{
...event,
syncedData: event.syncedData && {
...event.syncedData,
},
authorizedData: event.authorizedData && {
...event.authorizedData,
audioOnly: false, // TODO
},
}}
event={event}
/>}
<div>
<div>{event.title}</div>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/routes/manage/Video/Shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,16 @@ const query = graphql`
created
canWrite
isLive
audioOnly
acl { role actions info { label implies large } }
syncedData {
duration
updated
startTime
endTime
thumbnail
}
authorizedData {
thumbnail
tracks { flavor resolution mimetype uri }
}
series {
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/routes/manage/Video/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,18 @@ const query = graphql`
startIndex endIndex
}
items {
id title created description isLive tobiraDeletionTimestamp
id
title
created
description
isLive
tobiraDeletionTimestamp
audioOnly
series { id }
syncedData {
duration updated startTime endTime
duration thumbnail updated startTime endTime
}
authorizedData {
thumbnail
tracks { resolution }
}
}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ type SyncedEventData implements Node {
endTime: DateTimeUtc
"Duration in ms."
duration: Float!
thumbnail: String
}

input NewPlaylistBlock {
Expand Down Expand Up @@ -335,6 +336,7 @@ type AuthorizedEvent implements Node {
Otherwise, `false` is returned.
"""
isReferencedByRealm(path: String!): Boolean!
audioOnly: Boolean!
}

"A block just showing some title."
Expand Down Expand Up @@ -766,7 +768,6 @@ union RemoveMountedSeriesOutcome = RemovedRealm | RemovedBlock
"""
type AuthorizedEventData implements Node {
tracks: [Track!]!
thumbnail: String
captions: [Caption!]!
segments: [Segment!]!
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/ui/Blocks/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const VideoBlock: React.FC<Props> = ({ fragRef, basePath }) => {
updated
startTime
endTime
thumbnail
}
... VideoPageAuthorizedData
}
Expand All @@ -65,7 +66,6 @@ export const VideoBlock: React.FC<Props> = ({ fragRef, basePath }) => {
return unreachable();
}


return <div css={{ maxWidth: 800 }}>
{showTitle && <Title title={event.title} />}
<PlayerContextProvider>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ui/Blocks/VideoList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ export const videoListEventFragment = graphql`
creators
isLive
description
audioOnly
series { title id }
syncedData { duration startTime endTime }
syncedData { thumbnail duration startTime endTime }
authorizedData {
thumbnail
tracks { resolution }
}
}
Expand Down
Loading

0 comments on commit e373b7f

Please sign in to comment.