diff --git a/components/FolderGridLayout.tsx b/components/FolderGridLayout.tsx index dd39964..2daec92 100644 --- a/components/FolderGridLayout.tsx +++ b/components/FolderGridLayout.tsx @@ -12,17 +12,8 @@ import { getReadablePath } from '../utils/getReadablePath' import { Checkbox, ChildIcon, Downloading, formatChildName } from './FileListing' const GridItem = ({ c, path }: { c: OdFolderChildren; path: string }) => { - // We use the generated medium thumbnail for rendering preview images - const thumbnailUrl = - 'folder' in c - ? // Folders don't have thumbnails - null - : c.thumbnails && c.thumbnails.length > 0 - ? // Most OneDrive versions, including E5 developer, should have thumbnails returned - c.thumbnails[0].medium.url - : // According to OneDrive docs, OneDrive for Business and SharePoint does not - // (can not retrieve thumbnails via expand). But currently we only see OneDrive 世纪互联 really does not. - `/api/thumbnail?path=${path}` + // We use the generated medium thumbnail for rendering preview images (excluding folders) + const thumbnailUrl = 'folder' in c ? null : `/api/thumbnail?path=${path}&size=medium` // Some thumbnails are broken, so we check for onerror event in the image component const [brokenThumbnail, setBrokenThumbnail] = useState(false) diff --git a/components/previews/VideoPreview.tsx b/components/previews/VideoPreview.tsx index 89602ad..783a2e2 100644 --- a/components/previews/VideoPreview.tsx +++ b/components/previews/VideoPreview.tsx @@ -21,7 +21,7 @@ const VideoPreview: React.FC<{ file: OdFileObject }> = ({ file }) => { const { t } = useTranslation() // OneDrive generates thumbnails for its video files, we pick the thumbnail with the highest resolution - const thumbnail = file.thumbnails && file.thumbnails.length > 0 ? file.thumbnails[0].large.url : '' + const thumbnail = `/api/thumbnail?path=${asPath}&size=large` // We assume subtitle files are beside the video with the same name, only webvtt '.vtt' files are supported const subtitle = `/api?path=${asPath.replace(getExtension(file.name), 'vtt')}&raw=true` diff --git a/pages/api/index.ts b/pages/api/index.ts index 15994e2..5a73418 100644 --- a/pages/api/index.ts +++ b/pages/api/index.ts @@ -220,7 +220,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) headers: { Authorization: `Bearer ${accessToken}` }, params: { select: '@microsoft.graph.downloadUrl,name,size,id,lastModifiedDateTime,folder,file,video,image', - $expand: 'thumbnails', }, }) @@ -230,13 +229,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) params: next ? { select: '@microsoft.graph.downloadUrl,name,size,id,lastModifiedDateTime,folder,file,video,image', - $expand: 'thumbnails', top: siteConfig.maxItems, $skipToken: next, } : { select: '@microsoft.graph.downloadUrl,name,size,id,lastModifiedDateTime,folder,file,video,image', - $expand: 'thumbnails', top: siteConfig.maxItems, }, }) diff --git a/pages/api/thumbnail.ts b/pages/api/thumbnail.ts index 825f5bd..5ee18d7 100644 --- a/pages/api/thumbnail.ts +++ b/pages/api/thumbnail.ts @@ -13,8 +13,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) const accessToken = await getAccessToken() // Get item thumbnails by its path since we will later check if it is protected - const { path = '' } = req.query + const { path = '', size = 'medium' } = req.query + // Check whether the size is valid - must be one of 'large', 'medium', or 'small' + if (size !== 'large' && size !== 'medium' && size !== 'small') { + res.status(400).json({ error: 'Invalid size' }) + return + } // Sometimes the path parameter is defaulted to '[...path]' which we need to handle if (path === '[...path]') { res.status(400).json({ error: 'No path specified.' }) @@ -47,7 +52,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) headers: { Authorization: `Bearer ${accessToken}` }, }) - const thumbnailUrl = data.value && data.value.length > 0 ? (data.value[0] as OdThumbnail).medium.url : null + const thumbnailUrl = data.value && data.value.length > 0 ? (data.value[0] as OdThumbnail)[size].url : null if (thumbnailUrl) { res.redirect(thumbnailUrl) } else { diff --git a/types/index.d.ts b/types/index.d.ts index 817be66..06162d0 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -17,8 +17,8 @@ export type OdFolderObject = { folder?: { childCount: number; view: { sortBy: string; sortOrder: 'ascending'; viewType: 'thumbnails' } } image?: OdImageFile video?: OdVideoFile - 'thumbnails@odata.context'?: string - thumbnails?: Array + // 'thumbnails@odata.context'?: string + // thumbnails?: Array }> } export type OdFolderChildren = OdFolderObject['value'][number] @@ -33,8 +33,8 @@ export type OdFileObject = { file: { mimeType: string; hashes: { quickXorHash: string; sha1Hash?: string; sha256Hash?: string } } image?: OdImageFile video?: OdVideoFile - 'thumbnails@odata.context'?: string - thumbnails?: Array + // 'thumbnails@odata.context'?: string + // thumbnails?: Array } // A representation of a OneDrive image file. Some images do not return a width and height, so types are optional. export type OdImageFile = {