@@ -7,7 +7,7 @@ import {StackedModalProps, useParams} from '@alchemy/navigation';
7
7
import { Dimensions , filePlayerRelativeWrapperClassName } from '../Players' ;
8
8
import { Box , Typography } from '@mui/material' ;
9
9
import FileIntegrations from '../FileIntegrations.tsx' ;
10
- import { getAsset } from '../../../../api/asset.ts' ;
10
+ import { getAsset , getAssets } from '../../../../api/asset.ts' ;
11
11
import FullPageLoader from '../../../Ui/FullPageLoader.tsx' ;
12
12
import RouteDialog from '../../../Dialog/RouteDialog.tsx' ;
13
13
import { getAssetRenditions } from '../../../../api/rendition.ts' ;
@@ -31,6 +31,8 @@ import {
31
31
} from '../../../Discussion/discussion.ts' ;
32
32
import { useBindAnnotationMessage } from './useBindAnnotationMessage.ts' ;
33
33
import AssetViewInfo from '../AssetViewInfo.tsx' ;
34
+ import { ApiCollectionResponse } from '../../../../api/hydra.ts' ;
35
+ import StoryCarousel , { storyCarouselHeight } from './StoryCarousel.tsx' ;
34
36
35
37
export type IntegrationOverlayCommonProps = {
36
38
dimensions : Dimensions ;
@@ -53,6 +55,7 @@ type Props = {} & StackedModalProps;
53
55
export default function AssetView ( { modalIndex, open} : Props ) {
54
56
const menuWidth = 400 ;
55
57
const headerHeight = 60 ;
58
+ let heightRest = headerHeight ;
56
59
const { id : assetId , renditionId} = useParams ( ) ;
57
60
const assetAnnotationsRef : AssetAnnotationRef = useRef ( null ) ;
58
61
const messageFormRef : MessageFormRef = useRef ( null ) ;
@@ -62,6 +65,13 @@ export default function AssetView({modalIndex, open}: Props) {
62
65
> ( ) ;
63
66
const { t} = useTranslation ( ) ;
64
67
const queryKey = [ 'assets' , assetId ] ;
68
+ const [ storyAssets , setStoryAssets ] =
69
+ React . useState < ApiCollectionResponse < Asset > > ( ) ;
70
+ const [ currentStoryAsset , setCurrentStoryAsset ] = React . useState <
71
+ Asset | undefined
72
+ > ( ) ;
73
+
74
+ console . log ( 'currentStoryAsset' , currentStoryAsset ) ;
65
75
66
76
useChannelRegistration ( `asset-${ assetId } ` , `asset_ingested` , ( ) => {
67
77
queryClient . invalidateQueries ( { queryKey} ) ;
@@ -97,13 +107,6 @@ export default function AssetView({modalIndex, open}: Props) {
97
107
[ setIntegrationOverlay ]
98
108
) ;
99
109
100
- const dimensions = useMemo < Dimensions > ( ( ) => {
101
- return {
102
- width : winSize . innerWidth - menuWidth - scrollbarWidth ,
103
- height : winSize . innerHeight - headerHeight - 2 ,
104
- } ;
105
- } , [ winSize ] ) ;
106
-
107
110
const [ [ asset , renditions ] , rendition ] = (
108
111
isSuccess
109
112
? [
@@ -127,6 +130,28 @@ export default function AssetView({modalIndex, open}: Props) {
127
130
}
128
131
} , [ data , previousData , renditionId ] ) ;
129
132
133
+ const isStory = Boolean ( asset ?. storyCollection ) ;
134
+ if ( isStory ) {
135
+ heightRest += storyCarouselHeight ;
136
+ }
137
+
138
+ const dimensions = useMemo < Dimensions > ( ( ) => {
139
+ return {
140
+ width : winSize . innerWidth - menuWidth - scrollbarWidth ,
141
+ height : winSize . innerHeight - heightRest - 2 ,
142
+ } ;
143
+ } , [ winSize ] ) ;
144
+
145
+ React . useEffect ( ( ) => {
146
+ if ( asset ?. storyCollection ) {
147
+ getAssets ( {
148
+ parents : [ asset . storyCollection . id ] ,
149
+ } ) . then ( setStoryAssets ) ;
150
+ } else {
151
+ setStoryAssets ( undefined ) ;
152
+ }
153
+ } , [ asset ] ) ;
154
+
130
155
const {
131
156
onNewAnnotation,
132
157
onUpdateAnnotation,
@@ -148,6 +173,9 @@ export default function AssetView({modalIndex, open}: Props) {
148
173
return < FullPageLoader /> ;
149
174
}
150
175
176
+ const panelHeight = winSize . innerHeight - headerHeight ;
177
+ const displayedAsset = currentStoryAsset || asset ;
178
+
151
179
return (
152
180
< RouteDialog >
153
181
{ ( { onClose} ) => (
@@ -171,6 +199,7 @@ export default function AssetView({modalIndex, open}: Props) {
171
199
rendition = { rendition }
172
200
renditions = { renditions }
173
201
displayActions = { ! integrationOverlay }
202
+ isStory = { isStory }
174
203
/>
175
204
) : (
176
205
< div > </ div >
@@ -183,74 +212,104 @@ export default function AssetView({modalIndex, open}: Props) {
183
212
< >
184
213
< Box
185
214
sx = { {
186
- height : dimensions . height ,
187
215
display : 'flex' ,
188
216
flexDirection : 'row' ,
189
217
justifyContent : 'space-between' ,
190
218
} }
191
219
>
192
- < Box
193
- className = {
194
- filePlayerRelativeWrapperClassName
195
- }
196
- sx = { theme => ( {
197
- position : 'relative' ,
220
+ < div
221
+ style = { {
222
+ height : panelHeight ,
198
223
display : 'flex' ,
199
224
flexDirection : 'column' ,
200
- alignItems : 'center' ,
201
- justifyContent : 'center' ,
202
- overflowY : 'auto' ,
203
- height : dimensions . height ,
204
- width :
205
- dimensions . width + scrollbarWidth ,
206
- maxWidth :
207
- dimensions . width + scrollbarWidth ,
208
- backgroundColor :
209
- getMediaBackgroundColor ( theme ) ,
210
- } ) }
225
+ } }
211
226
>
212
- { rendition ?. file &&
213
- ( ! integrationOverlay ||
214
- ! integrationOverlay . replace ) && (
215
- < MemoizedFilePlayer
216
- assetAnnotationsRef = {
217
- assetAnnotationsRef
218
- }
219
- onNewAnnotation = {
220
- onNewAnnotation
221
- }
222
- onUpdateAnnotation = {
223
- onUpdateAnnotation
224
- }
225
- onDeleteAnnotation = {
226
- onDeleteAnnotation
227
+ < Box
228
+ className = {
229
+ filePlayerRelativeWrapperClassName
230
+ }
231
+ sx = { theme => ( {
232
+ position : 'relative' ,
233
+ display : 'flex' ,
234
+ flexDirection : 'column' ,
235
+ alignItems : 'center' ,
236
+ justifyContent : 'center' ,
237
+ overflowY : 'auto' ,
238
+ height : dimensions . height ,
239
+ width :
240
+ dimensions . width +
241
+ scrollbarWidth ,
242
+ maxWidth :
243
+ dimensions . width +
244
+ scrollbarWidth ,
245
+ backgroundColor :
246
+ getMediaBackgroundColor ( theme ) ,
247
+ } ) }
248
+ >
249
+ { ( currentStoryAsset ||
250
+ rendition ?. file ) &&
251
+ ( ! integrationOverlay ||
252
+ ! integrationOverlay . replace ) && (
253
+ < MemoizedFilePlayer
254
+ assetAnnotationsRef = {
255
+ assetAnnotationsRef
256
+ }
257
+ onNewAnnotation = {
258
+ onNewAnnotation
259
+ }
260
+ onUpdateAnnotation = {
261
+ onUpdateAnnotation
262
+ }
263
+ onDeleteAnnotation = {
264
+ onDeleteAnnotation
265
+ }
266
+ annotations = { annotations }
267
+ file = {
268
+ currentStoryAsset
269
+ ?. original ?. file ||
270
+ currentStoryAsset
271
+ ?. preview ?. file ||
272
+ currentStoryAsset
273
+ ?. thumbnail ?. file ||
274
+ rendition ?. file
275
+ }
276
+ title = { displayedAsset . title }
277
+ dimensions = { dimensions }
278
+ autoPlayable = { false }
279
+ controls = { true }
280
+ zoomEnabled = { true }
281
+ />
282
+ ) }
283
+ { integrationOverlay &&
284
+ React . createElement (
285
+ integrationOverlay . component ,
286
+ {
287
+ dimensions,
288
+ ...( integrationOverlay . props ||
289
+ { } ) ,
227
290
}
228
- annotations = { annotations }
229
- file = { rendition . file }
230
- title = { asset . title }
231
- dimensions = { dimensions }
232
- autoPlayable = { false }
233
- controls = { true }
234
- zoomEnabled = { true }
235
- />
236
- ) }
237
- { integrationOverlay &&
238
- React . createElement (
239
- integrationOverlay . component ,
240
- {
241
- dimensions,
242
- ...( integrationOverlay . props ||
243
- { } ) ,
244
- }
245
- ) }
246
- </ Box >
291
+ ) }
292
+ </ Box >
293
+
294
+ { isStory ? (
295
+ < StoryCarousel
296
+ assets = { storyAssets }
297
+ selectedAsset = { displayedAsset }
298
+ story = { asset }
299
+ onAssetClick = { a => {
300
+ setCurrentStoryAsset ( a ) ;
301
+ } }
302
+ />
303
+ ) : null }
304
+ </ div >
305
+
247
306
< Box
248
307
sx = { theme => ( {
249
308
width : menuWidth ,
250
309
maxWidth : menuWidth ,
251
310
borderLeft : `1px solid ${ theme . palette . divider } ` ,
252
311
overflowY : 'auto' ,
253
- height : dimensions . height ,
312
+ height : panelHeight ,
254
313
} ) }
255
314
>
256
315
< AssetAttributes
0 commit comments