clamp multiple lines for long file names

This commit is contained in:
spencerwooo 2022-02-05 20:36:38 +08:00
parent 443d42b16c
commit b42036afb7
No known key found for this signature in database
GPG key ID: 24CD550268849CA0
9 changed files with 65 additions and 40 deletions

View file

@ -43,6 +43,7 @@ import FolderListLayout from './FolderListLayout'
import type { OdFileObject, OdFolderObject } from '../types'
import FolderGridLayout from './FolderGridLayout'
import ImagePreview from './previews/ImagePreview'
// Disabling SSR for some previews
const EPUBPreview = dynamic(() => import('./previews/EPUBPreview'), {
@ -340,29 +341,12 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
const fileName = file.name
const fileExtension = fileName.slice(((fileName.lastIndexOf('.') - 1) >>> 0) + 2).toLowerCase()
const previewType = getPreviewType(fileExtension, {
video: Boolean(file.video),
})
const previewType = getPreviewType(fileExtension, { video: Boolean(file.video) })
if (previewType) {
switch (previewType) {
case preview.image:
return (
<>
<PreviewContainer>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
className="mx-auto"
src={downloadUrl}
alt={fileName}
width={file.image?.width}
height={file.image?.height}
/>
</PreviewContainer>
<DownloadBtnContainer>
<DownloadButtonGroup downloadUrl={file['@microsoft.graph.downloadUrl']} />
</DownloadBtnContainer>
</>
)
return <ImagePreview file={file} />
case preview.text:
return <TextPreview file={file} />

View file

@ -1,5 +1,6 @@
import type { OdFolderObject } from '../types'
import { useState } from 'react'
import Link from 'next/link'
import emojiRegex from 'emoji-regex'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
@ -9,7 +10,6 @@ import { getFileIcon } from '../utils/getFileIcon'
import { getBaseUrl } from '../utils/getBaseUrl'
import { formatModifiedDateTime } from '../utils/fileDetails'
import { Checkbox, Downloading } from './FileListing'
import { useState } from 'react'
type OdFolderChildren = OdFolderObject['value'][number]

View file

@ -14,38 +14,38 @@ export const SwitchLayout = () => {
const [preferredLayout, setPreferredLayout] = useLocalStorage('preferredLayout', layouts[0])
return (
<div className="w-24 flex-shrink-0 text-sm text-gray-600 dark:text-gray-300 md:w-28">
<div className="relative w-24 flex-shrink-0 text-sm text-gray-600 dark:text-gray-300 md:w-28">
<Listbox value={preferredLayout} onChange={setPreferredLayout}>
<Listbox.Button className="relative w-full cursor-pointer rounded pl-2">
<span className="pointer-events-none flex items-center">
<FontAwesomeIcon className="mr-2 h-4 w-4" icon={preferredLayout.icon} />
<FontAwesomeIcon className="mr-2 h-3 w-3" icon={preferredLayout.icon} />
<span>{preferredLayout.name}</span>
</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<FontAwesomeIcon className="h-4 w-4" icon="chevron-down" />
<FontAwesomeIcon className="h-3 w-3" icon="chevron-down" />
</span>
</Listbox.Button>
<Transition as={Fragment} leave="transition ease-in duration-100" leaveFrom="opacity-100" leaveTo="opacity-0">
<Listbox.Options className="absolute z-20 mt-1 w-36 overflow-auto rounded border border-gray-900/10 bg-white py-1 shadow-lg focus:outline-none dark:border-gray-500/30 dark:bg-gray-800">
<Listbox.Options className="absolute right-0 z-20 mt-1 w-32 overflow-auto rounded border border-gray-900/10 bg-white py-1 shadow-lg focus:outline-none dark:border-gray-500/30 dark:bg-gray-800">
{layouts.map(layout => (
<Listbox.Option
key={layout.id}
className={`${
layout.name === preferredLayout.name &&
'bg-blue-50 text-blue-700 dark:bg-blue-600/10 dark:text-blue-400'
} relative flex cursor-pointer select-none items-center py-1.5 pl-9 text-gray-600 hover:opacity-80 dark:text-gray-300`}
} relative flex cursor-pointer select-none items-center py-1.5 pl-3 text-gray-600 hover:opacity-80 dark:text-gray-300`}
value={layout}
>
{layout.name === preferredLayout.name && (
<span className="absolute inset-y-0 left-0 flex items-center pl-3">
<FontAwesomeIcon className="h-4 w-4" icon="check" />
</span>
)}
<FontAwesomeIcon className="mr-2 h-4 w-4" icon={layout.icon} />
<FontAwesomeIcon className="mr-2 h-3 w-3" icon={layout.icon} />
<span className={layout.name === preferredLayout.name ? 'font-medium' : 'font-normal'}>
{layout.name}
</span>
{layout.name === preferredLayout.name && (
<span className="absolute inset-y-0 right-3 flex items-center">
<FontAwesomeIcon className="h-3 w-3" icon="check" />
</span>
)}
</Listbox.Option>
))}
</Listbox.Options>

View file

@ -14,9 +14,9 @@ const DefaultPreview: FC<{ file: OdFileObject }> = ({ file }) => {
<div>
<PreviewContainer>
<div className="items-center px-5 py-4 md:flex md:space-x-8">
<div className="rounded-lg border border-gray-900/10 px-10 py-20 text-center dark:border-gray-500/30">
<div className="rounded-lg border border-gray-900/10 px-8 py-20 text-center dark:border-gray-500/30">
<FontAwesomeIcon icon={getFileIcon(file.name, { video: Boolean(file.video) })} />
<div className="mt-6 overflow-hidden truncate text-sm font-medium md:w-20">{file.name}</div>
<div className="mt-6 text-sm font-medium line-clamp-3 md:w-28">{file.name}</div>
</div>
<div className="flex flex-col space-y-2 py-4 md:flex-1">
@ -32,7 +32,7 @@ const DefaultPreview: FC<{ file: OdFileObject }> = ({ file }) => {
<div>
<div className="py-2 text-xs font-medium uppercase opacity-80">MIME type</div>
<div>{file.file.mimeType}</div>
<div>{file.file?.mimeType || 'Unavailable'}</div>
</div>
<div>
@ -44,7 +44,7 @@ const DefaultPreview: FC<{ file: OdFileObject }> = ({ file }) => {
Quick XOR
</td>
<td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.quickXorHash}
{file.file.hashes?.quickXorHash || 'Unavailable'}
</td>
</tr>
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
@ -52,7 +52,7 @@ const DefaultPreview: FC<{ file: OdFileObject }> = ({ file }) => {
SHA1
</td>
<td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.sha1Hash}
{file.file.hashes?.sha1Hash || 'Unavailable'}
</td>
</tr>
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
@ -60,7 +60,7 @@ const DefaultPreview: FC<{ file: OdFileObject }> = ({ file }) => {
SHA256
</td>
<td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.sha256Hash}
{file.file.hashes?.sha256Hash || 'Unavailable'}
</td>
</tr>
</tbody>

View file

@ -0,0 +1,28 @@
import type { OdFileObject } from '../../types'
import { FC } from 'react'
import { PreviewContainer, DownloadBtnContainer } from './Containers'
import DownloadButtonGroup from '../DownloadBtnGtoup'
const ImagePreview: FC<{ file: OdFileObject }> = ({ file }) => {
return (
<>
<PreviewContainer>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
className="mx-auto"
src={file['@microsoft.graph.downloadUrl']}
alt={file.name}
width={file.image?.width}
height={file.image?.height}
/>
</PreviewContainer>
<DownloadBtnContainer>
<DownloadButtonGroup downloadUrl={file['@microsoft.graph.downloadUrl']} />
</DownloadBtnContainer>
</>
)
}
export default ImagePreview

View file

@ -16,6 +16,7 @@
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"@headlessui/react": "^1.4.0",
"@tailwindcss/line-clamp": "^0.3.1",
"awesome-debounce-promise": "^2.1.0",
"axios": "^0.25.0",
"cors": "^2.8.5",

View file

@ -7,6 +7,7 @@ specifiers:
'@fortawesome/free-solid-svg-icons': ^5.15.3
'@fortawesome/react-fontawesome': ^0.1.14
'@headlessui/react': ^1.4.0
'@tailwindcss/line-clamp': ^0.3.1
'@types/cors': ^2.8.12
'@types/crypto-js': ^4.0.2
'@types/ioredis': ^4.28.5
@ -62,6 +63,7 @@ dependencies:
'@fortawesome/free-solid-svg-icons': 5.15.4
'@fortawesome/react-fontawesome': 0.1.17_f515edce028694561ceb456e3dba224c
'@headlessui/react': 1.4.3_react-dom@17.0.2+react@17.0.2
'@tailwindcss/line-clamp': 0.3.1_tailwindcss@3.0.18
awesome-debounce-promise: 2.1.0
axios: 0.25.0
cors: 2.8.5
@ -376,6 +378,14 @@ packages:
resolution: {integrity: sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==}
dev: true
/@tailwindcss/line-clamp/0.3.1_tailwindcss@3.0.18:
resolution: {integrity: sha512-pNr0T8LAc3TUx/gxCfQZRe9NB2dPEo/cedPHzUGIPxqDMhgjwNm6jYxww4W5l0zAsAddxr+XfZcqttGiFDgrGg==}
peerDependencies:
tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1'
dependencies:
tailwindcss: 3.0.18_833e1018ad0d7954aa80c53675939269
dev: false
/@types/cors/2.8.12:
resolution: {integrity: sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==}
dev: true

View file

@ -35,5 +35,7 @@ module.exports = {
}
}
},
plugins: [],
plugins: [
require('@tailwindcss/line-clamp'),
],
}

2
types/index.d.ts vendored
View file

@ -13,7 +13,7 @@ export type OdFolderObject = {
name: string
size: number
lastModifiedDateTime: string
file?: { mimeType: string; hashes: { quickXorHash: string; sha1Hash?: string; sha256Hash?: string } }
file?: { mimeType: string; hashes: { quickXorHash?: string; sha1Hash?: string; sha256Hash?: string } }
folder?: { childCount: number; view: { sortBy: string; sortOrder: 'ascending'; viewType: 'thumbnails' } }
image?: OdImageFile
video?: OdVideoFile