formatting tailwind classes with prettier

This commit is contained in:
spencerwooo 2022-02-04 16:05:28 +08:00
parent d8ef0733bf
commit e4f3ea7b05
No known key found for this signature in database
GPG key ID: 24CD550268849CA0
22 changed files with 252 additions and 149 deletions

View file

@ -1,3 +1,3 @@
{
"extends": ["next", "next/core-web-vitals"]
"extends": ["next", "next/core-web-vitals", "prettier"]
}

36
.gitignore vendored
View file

@ -35,3 +35,39 @@ yarn-error.log*
# redis dump
dump.rdb
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
.vscode/*
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix

9
.prettierrc.js Normal file
View file

@ -0,0 +1,9 @@
module.exports = {
printWidth: 120,
arrowParens: "avoid",
singleQuote: true,
semi: false,
plugins: [
require('prettier-plugin-tailwindcss')
]
}

View file

@ -41,7 +41,9 @@ import type { OdFileObject, OdFolderObject } from '../types'
// Disabling SSR for some previews (image gallery view, and PDF view)
const ReactViewer = dynamic(() => import('react-viewer'), { ssr: false })
const EPUBPreview = dynamic(() => import('./previews/EPUBPreview'), { ssr: false })
const EPUBPreview = dynamic(() => import('./previews/EPUBPreview'), {
ssr: false,
})
/**
* Convert url query into path string
@ -151,7 +153,9 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
const [selected, setSelected] = useState<{ [key: string]: boolean }>({})
const [totalSelected, setTotalSelected] = useState<0 | 1 | 2>(0)
const [totalGenerating, setTotalGenerating] = useState<boolean>(false)
const [folderGenerating, setFolderGenerating] = useState<{ [key: string]: boolean }>({})
const [folderGenerating, setFolderGenerating] = useState<{
[key: string]: boolean
}>({})
const router = useRouter()
const clipboard = useClipboard()
@ -283,7 +287,9 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
downloadMultipleFiles({ toastId, router, files, folder })
.then(() => {
setTotalGenerating(false)
toast.success('Finished downloading selected files.', { id: toastId })
toast.success('Finished downloading selected files.', {
id: toastId,
})
})
.catch(() => {
setTotalGenerating(false)
@ -312,7 +318,13 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
setFolderGenerating({ ...folderGenerating, [id]: true })
const toastId = toast.loading(DownloadingToast(router))
downloadTreelikeMultipleFiles({ toastId, router, files, basePath: path, folder: name })
downloadTreelikeMultipleFiles({
toastId,
router,
files,
basePath: path,
folder: name,
})
.then(() => {
setFolderGenerating({ ...folderGenerating, [id]: false })
toast.success('Finished downloading folder.', { id: toastId })
@ -394,7 +406,9 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
render: <FontAwesomeIcon icon={['fas', 'copy']} />,
onClick: i => {
clipboard.copy(i.alt ? `${getBaseUrl()}/api?path=${path + '/' + i.alt}&raw=true` : '')
toast('Copied image permanent link to clipboard.', { icon: '👌' })
toast('Copied image permanent link to clipboard.', {
icon: '👌',
})
},
},
])
@ -544,7 +558,9 @@ 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:

View file

@ -4,7 +4,7 @@ const FourOhFour: React.FC<{ errorMsg: string }> = ({ errorMsg }) => {
return (
<div className="my-12">
<div className="w-1/3 mx-auto">
<Image src='/images/fabulous-rip-2.png' alt="404" width={912} height={912} priority />
<Image src="/images/fabulous-rip-2.png" alt="404" width={912} height={912} priority />
</div>
<div className="mt-6 text-gray-500 max-w-xl mx-auto">
<div className="text-xl font-bold mb-8">

View file

@ -81,7 +81,9 @@ export async function downloadMultipleFiles({
// Create zip file and download it
const b = await zip.generateAsync({ type: 'blob' }, metadata => {
toast.loading(DownloadingToast(router, metadata.percent.toFixed(0)), { id: toastId })
toast.loading(DownloadingToast(router, metadata.percent.toFixed(0)), {
id: toastId,
})
})
downloadBlob({ blob: b, name: folder ? folder + '.zip' : 'download.zip' })
}
@ -147,7 +149,9 @@ export async function downloadTreelikeMultipleFiles({
// Create zip file and download it
const b = await zip.generateAsync({ type: 'blob' }, metadata => {
toast.loading(DownloadingToast(router, metadata.percent.toFixed(0)), { id: toastId })
toast.loading(DownloadingToast(router, metadata.percent.toFixed(0)), {
id: toastId,
})
})
downloadBlob({ blob: b, name: folder ? folder + '.zip' : 'download.zip' })
}
@ -214,7 +218,7 @@ export async function* traverseFolder(path: string): AsyncGenerator<
isFolder: boolean
error?: { status: number; message: string }
}[]
yield * items
yield* items
folderPaths = items
.filter(({ error }) => !error)
.filter(i => i.isFolder)

View file

@ -21,10 +21,10 @@ const AudioPreview: FC<{ file: OdFileObject }> = ({ file }) => {
return (
<>
<PreviewContainer>
<div className="md:flex-row md:space-x-4 flex flex-col space-y-4">
<div className="dark:bg-gray-700 aspect-square flex items-center justify-center w-full md:w-40 transition-all duration-75 bg-gray-100 rounded">
<div className="flex flex-col space-y-4 md:flex-row md:space-x-4">
<div className="flex aspect-square w-full items-center justify-center rounded bg-gray-100 transition-all duration-75 dark:bg-gray-700 md:w-40">
{playerStatus === PlayerState.Loading ? (
<LoadingIcon className="animate-spin w-5 h-5 inline-block" />
<LoadingIcon className="inline-block h-5 w-5 animate-spin" />
) : (
<FontAwesomeIcon
className={`h-5 w-5 ${playerStatus === PlayerState.Playing ? 'animate-spin' : ''}`}
@ -33,7 +33,7 @@ const AudioPreview: FC<{ file: OdFileObject }> = ({ file }) => {
/>
)}
</div>
<div className="flex flex-col w-full space-y-2">
<div className="flex w-full flex-col space-y-2">
<div>{file.name}</div>
<div className="pb-4 text-sm text-gray-500">
Last modified:{' '}
@ -44,7 +44,7 @@ const AudioPreview: FC<{ file: OdFileObject }> = ({ file }) => {
</div>
<ReactAudioPlayer
className="w-full h-11"
className="h-11 w-full"
src={file['@microsoft.graph.downloadUrl']}
controls
onCanPlay={() => setPlayerStatus(PlayerState.Ready)}

View file

@ -1,10 +1,10 @@
export function PreviewContainer({ children }): JSX.Element {
return <div className="dark:bg-gray-900 p-3 bg-white rounded dark:text-white">{children}</div>
return <div className="rounded bg-white p-3 dark:bg-gray-900 dark:text-white">{children}</div>
}
export function DownloadBtnContainer({ children }): JSX.Element {
return (
<div className="border-t rounded border-gray-900/10 dark:border-gray-500/30 p-2 sticky bottom-0 left-0 right-0 z-10 bg-white bg-opacity-80 backdrop-blur-md dark:bg-gray-900">
<div className="sticky bottom-0 left-0 right-0 z-10 rounded border-t border-gray-900/10 bg-white bg-opacity-80 p-2 backdrop-blur-md dark:border-gray-500/30 dark:bg-gray-900">
{children}
</div>
)

View file

@ -13,53 +13,53 @@ const DefaultPreview: FC<{ file: OdFileObject }> = ({ file }) => {
return (
<div>
<PreviewContainer>
<div className="md:flex px-5 py-4 md:space-x-8 items-center">
<div className="text-center border rounded-lg px-10 py-20 border-gray-900/10 dark:border-gray-500/30">
<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">
<FontAwesomeIcon icon={getFileIcon(file.name, { video: Boolean(file.video) })} />
<div className="font-medium text-sm mt-6 md:w-20 overflow-hidden truncate">{file.name}</div>
<div className="mt-6 overflow-hidden truncate text-sm font-medium md:w-20">{file.name}</div>
</div>
<div className="md:flex-1 flex flex-col py-4 space-y-2">
<div className="flex flex-col space-y-2 py-4 md:flex-1">
<div>
<div className="font-medium text-xs opacity-80 uppercase py-2">Last modified</div>
<div className="py-2 text-xs font-medium uppercase opacity-80">Last modified</div>
<div>{formatModifiedDateTime(file.lastModifiedDateTime)}</div>
</div>
<div>
<div className="font-medium text-xs opacity-80 uppercase py-2">File size</div>
<div className="py-2 text-xs font-medium uppercase opacity-80">File size</div>
<div>{humanFileSize(file.size)}</div>
</div>
<div>
<div className="font-medium text-xs opacity-80 uppercase py-2">MIME type</div>
<div className="py-2 text-xs font-medium uppercase opacity-80">MIME type</div>
<div>{file.file.mimeType}</div>
</div>
<div>
<div className="font-medium text-xs opacity-80 uppercase py-2">Hashes</div>
<table className="w-full overflow-scroll block md:table whitespace-nowrap text-sm">
<div className="py-2 text-xs font-medium uppercase opacity-80">Hashes</div>
<table className="block w-full overflow-scroll whitespace-nowrap text-sm md:table">
<tbody>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
Quick XOR
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400 font-mono">
<td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.quickXorHash}
</td>
</tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
SHA1
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400 font-mono">
<td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.sha1Hash}
</td>
</tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
SHA256
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400 font-mono">
<td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.sha256Hash}
</td>
</tr>

View file

@ -36,11 +36,17 @@ const EPUBPreview: FC<{ file: OdFileObject }> = ({ file }) => {
return (
<div>
<div
className="dark:bg-gray-900 md:p-3 no-scrollbar flex flex-col w-full overflow-scroll bg-white rounded"
className="no-scrollbar flex w-full flex-col overflow-scroll rounded bg-white dark:bg-gray-900 md:p-3"
style={{ maxHeight: '90vh' }}
>
<div className="no-scrollbar flex-1 w-full overflow-scroll" ref={epubContainer} style={{ minHeight: '70vh' }}>
<div style={{ position: 'absolute', width: epubContainerWidth, height: '70vh' }}>
<div className="no-scrollbar w-full flex-1 overflow-scroll" ref={epubContainer} style={{ minHeight: '70vh' }}>
<div
style={{
position: 'absolute',
width: epubContainerWidth,
height: '70vh',
}}
>
<ReactReader
url={file['@microsoft.graph.downloadUrl']}
getRendition={rendition => fixEpub(rendition)}

View file

@ -14,11 +14,11 @@ import DownloadButtonGroup from '../DownloadBtnGtoup'
import useAxiosGet from '../../utils/fetchOnMount'
import { DownloadBtnContainer, PreviewContainer } from './Containers'
const MarkdownPreview: FC<{ file: any; path: string; standalone?: boolean }> = ({
file,
path,
standalone = true,
}) => {
const MarkdownPreview: FC<{
file: any
path: string
standalone?: boolean
}> = ({ file, path, standalone = true }) => {
const { response: content, error, validating } = useAxiosGet(file['@microsoft.graph.downloadUrl'])
// The parent folder of the markdown file, which is also the relative image folder

View file

@ -9,7 +9,7 @@ const PDFEmbedPreview: React.FC<{ file: any }> = ({ file }) => {
return (
<div>
<div className="w-full rounded overflow-hidden" style={{ height: '90vh' }}>
<div className="w-full overflow-hidden rounded" style={{ height: '90vh' }}>
<iframe src={url} frameBorder="0" width="100%" height="100%"></iframe>
</div>
<DownloadBtnContainer>

View file

@ -33,7 +33,7 @@ const TextPreview = ({ file }) => {
return (
<div>
<PreviewContainer>
<pre className="md:p-3 p-0 overflow-x-scroll text-sm">{content}</pre>
<pre className="overflow-x-scroll p-0 text-sm md:p-3">{content}</pre>
</PreviewContainer>
<DownloadBtnContainer>
<DownloadButtonGroup downloadUrl={file['@microsoft.graph.downloadUrl']} />

View file

@ -40,7 +40,7 @@ const TextPreview = ({ file }) => {
return (
<div>
<PreviewContainer>
<pre className="md:p-3 p-0 overflow-x-scroll text-sm">{content}</pre>
<pre className="overflow-x-scroll p-0 text-sm md:p-3">{content}</pre>
</PreviewContainer>
<DownloadBtnContainer>
<div className="flex justify-center">

View file

@ -27,7 +27,10 @@ const VideoPreview: React.FC<{ file: OdFileObject }> = ({ file }) => {
options={{
volume: 1.0,
lang: 'en',
video: { url: file['@microsoft.graph.downloadUrl'], pic: thumbnail },
video: {
url: file['@microsoft.graph.downloadUrl'],
pic: thumbnail,
},
subtitle: { url: subtitle },
}}
/>

View file

@ -10,22 +10,22 @@
module.exports = {
// The clientId and clientSecret are used to authenticate the user with Microsoft Graph API using OAuth. You would
// not need to change anything here if you can authenticate with your personal Microsoft account with OneDrive International.
clientId: "d87bcc39-1750-4ca0-ad54-f8d0efbb2735",
obfuscatedClientSecret: "U2FsdGVkX1830zo3/pFDqaBCVBb37iLw3WnBDWGF9GIB2f4apzv0roemp8Y+iIxI3Ih5ecyukqELQEGzZlYiWg==",
clientId: 'd87bcc39-1750-4ca0-ad54-f8d0efbb2735',
obfuscatedClientSecret: 'U2FsdGVkX1830zo3/pFDqaBCVBb37iLw3WnBDWGF9GIB2f4apzv0roemp8Y+iIxI3Ih5ecyukqELQEGzZlYiWg==',
// The redirectUri is the URL that the user will be redirected to after they have authenticated with Microsoft Graph API.
// Likewise, you would not need to change redirectUri if you are using your personal Microsoft account with OneDrive International.
redirectUri: "http://localhost",
redirectUri: 'http://localhost',
// These are the URLs of the OneDrive API endpoints. You would not need to change anything here if you are using OneDrive International
// or E5 Subscription OneDrive for Business. You may need to change these if you are using OneDrive 世纪互联.
authApi: "https://login.microsoftonline.com/common/oauth2/v2.0/token",
driveApi: "https://graph.microsoft.com/v1.0/me/drive",
authApi: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
driveApi: 'https://graph.microsoft.com/v1.0/me/drive',
// The scope we require are listed here, in most cases you would not need to change this as well.
scope: "user.read files.read.all offline_access",
scope: 'user.read files.read.all offline_access',
// The directLinkRegex is used to match the direct link of the file from the response of the API. We originally use this to prevent
// unauthorised use of the proxied download feature - but that is disabled for now. So you can safely ignore this settings.
directLinkRegex: "public[.].*[.]files[.]1drv[.]com"
directLinkRegex: 'public[.].*[.]files[.]1drv[.]com',
}

View file

@ -7,17 +7,17 @@ module.exports = {
// Make sure this is exactly the same as the email address you use to sign into your Microsoft account.
// You can also put this in your Vercel's environment variable 'NEXT_PUBLIC_USER_PRINCIPLE_NAME' if you worry about
// your email being exposed in public.
userPrincipalName: process.env.NEXT_PUBLIC_USER_PRINCIPLE_NAME || "spencer@spwoo.onmicrosoft.com",
userPrincipalName: process.env.NEXT_PUBLIC_USER_PRINCIPLE_NAME || 'spencer@spwoo.onmicrosoft.com',
// [OPTIONAL] This is the website icon to the left of the title inside the navigation bar. It should be placed under the
// /public directory of your GitHub project (not your OneDrive folder!), and referenced here by its relative path to /public.
icon: "/icons/128.png",
icon: '/icons/128.png',
// The name of your website. Present alongside your icon.
title: "Spencer's OneDrive",
// The folder that you are to share publicly with onedrive-vercel-index. Use '/' if you want to share your root folder.
baseDirectory: "/",
baseDirectory: '/',
// [OPTIONAL] This represents the maximum number of items that one directory lists, pagination supported.
// Do note that this is limited up to 200 items by the upstream OneDrive API.
@ -26,39 +26,35 @@ module.exports = {
// [OPTIONAL] We use Google Fonts natively for font customisations.
// You can check and generate the required links and names at https://fonts.google.com.
// googleFontSans - the sans serif font used in onedrive-vercel-index.
googleFontSans: "Inter",
googleFontSans: 'Inter',
// googleFontMono - the monospace font used in onedrive-vercel-index.
googleFontMono: "Fira Mono",
googleFontMono: 'Fira Mono',
// googleFontLinks - an array of links for referencing the google font assets.
googleFontLinks: [
"https://fonts.googleapis.com/css2?family=Fira+Mono&family=Inter:wght@400;500;700&display=swap"
],
googleFontLinks: ['https://fonts.googleapis.com/css2?family=Fira+Mono&family=Inter:wght@400;500;700&display=swap'],
// [OPTIONAL] The footer component of your website. You can write HTML here, but you need to escape double
// quotes - changing " to \". You can write anything here, and if you like badges, generate some with https://shields.io
footer: "Powered by <a href=\"https://github.com/spencerwooo/onedrive-vercel-index\" target=\"_blank\" rel=\"noopener noreferrer\">onedrive-vercel-index</a>. Made with ❤ by SpencerWoo.",
footer:
'Powered by <a href="https://github.com/spencerwooo/onedrive-vercel-index" target="_blank" rel="noopener noreferrer">onedrive-vercel-index</a>. Made with ❤ by SpencerWoo.',
// [OPTIONAL] This is where you specify the folders that are password protected. It is an array of paths pointing to all
// the directories in which you have .password set. Check the documentation for details.
protectedRoutes: [
"/🌞 Private folder/u-need-a-password",
"/🥟 Some test files/Protected route"
],
protectedRoutes: ['/🌞 Private folder/u-need-a-password', '/🥟 Some test files/Protected route'],
// [OPTIONAL] Use "" here if you want to remove this email address from the nav bar.
email: "mailto:spencer.wushangbo@gmail.com",
email: 'mailto:spencer.wushangbo@gmail.com',
// [OPTIONAL] This is an array of names and links for setting your social information and links.
// In the latest update, all brand icons inside font awesome is supported and the icon to render is based on the name
// you provide. See the documentation for details.
links: [
{
"name": "GitHub",
"link": "https://github.com/spencerwooo/onedrive-vercel-index"
name: 'GitHub',
link: 'https://github.com/spencerwooo/onedrive-vercel-index',
},
{
"name": "Telegram",
"link": "https://t.me/realSpencerWoo"
}
]
name: 'Telegram',
link: 'https://t.me/realSpencerWoo',
},
],
}

View file

@ -6,7 +6,8 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"format": "prettier components/**/*.tsx config/*.js pages/**/*.tsx {types,utils}/**/*.ts --write"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
@ -58,7 +59,10 @@
"autoprefixer": "^10.4.0",
"eslint": "8.8.0",
"eslint-config-next": "12.0.10",
"eslint-config-prettier": "^8.3.0",
"postcss": "^8.4.5",
"prettier": "^2.5.1",
"prettier-plugin-tailwindcss": "^0.1.4",
"tailwindcss": "^3.0.18",
"typescript": "4.5.5"
}

View file

@ -12,24 +12,24 @@ export default function OAuthStep1() {
const router = useRouter()
return (
<div className="dark:bg-gray-900 flex flex-col items-center justify-center min-h-screen bg-white">
<div className="flex min-h-screen flex-col items-center justify-center bg-white dark:bg-gray-900">
<Head>
<title>{`OAuth Step 1 - ${siteConfig.title}`}</title>
</Head>
<main className="bg-gray-50 dark:bg-gray-800 flex flex-col flex-1 w-full">
<main className="flex w-full flex-1 flex-col bg-gray-50 dark:bg-gray-800">
<Navbar />
<div className="w-full max-w-5xl p-4 mx-auto">
<div className="dark:bg-gray-900 dark:text-gray-100 bg-white rounded p-3">
<div className="mx-auto w-full max-w-5xl p-4">
<div className="rounded bg-white p-3 dark:bg-gray-900 dark:text-gray-100">
<div className="mx-auto w-52">
<Image src="/images/fabulous-fireworks.png" width={912} height={912} alt="fabulous fireworks" priority />
</div>
<h3 className="font-medium text-xl mb-4 text-center">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="mb-4 text-center text-xl font-medium">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="font-medium text-lg mt-4 mb-2">Step 1/3: Preparations</h3>
<h3 className="mt-4 mb-2 text-lg font-medium">Step 1/3: Preparations</h3>
<p className="py-1 text-yellow-400 font-medium text-sm">
<p className="py-1 text-sm font-medium text-yellow-400">
<FontAwesomeIcon icon="exclamation-triangle" className="mr-1" /> If you have not specified a REDIS_URL
inside your Vercel env variable, go initialise one at{' '}
<a href="https://upstash.com/" target="_blank" rel="noopener noreferrer" className="underline">
@ -49,76 +49,76 @@ export default function OAuthStep1() {
<p className="py-1">
Authorisation is required as no valid{' '}
<code className="text-sm font-mono underline decoration-wavy decoration-pink-600">access_token</code> or{' '}
<code className="text-sm font-mono underline decoration-wavy decoration-green-600">refresh_token</code> is
<code className="font-mono text-sm underline decoration-pink-600 decoration-wavy">access_token</code> or{' '}
<code className="font-mono text-sm underline decoration-green-600 decoration-wavy">refresh_token</code> is
present on this deployed instance. Check the following configurations before proceeding with authorising
onedrive-vercel-index with your own Microsoft account.
</p>
<div className="overflow-hidden my-4">
<table className="table-auto min-w-full">
<div className="my-4 overflow-hidden">
<table className="min-w-full table-auto">
<tbody>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
CLIENT_ID
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.clientId}</code>
<td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="font-mono text-sm">{apiConfig.clientId}</code>
</td>
</tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
CLIENT_SECRET*
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.obfuscatedClientSecret}</code>
<td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="font-mono text-sm">{apiConfig.obfuscatedClientSecret}</code>
</td>
</tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
REDIRECT_URI
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.redirectUri}</code>
<td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="font-mono text-sm">{apiConfig.redirectUri}</code>
</td>
</tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
Auth API URL
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.authApi}</code>
<td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="font-mono text-sm">{apiConfig.authApi}</code>
</td>
</tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
Drive API URL
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.driveApi}</code>
<td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="font-mono text-sm">{apiConfig.driveApi}</code>
</td>
</tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
<tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
API Scope
</td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.scope}</code>
<td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="font-mono text-sm">{apiConfig.scope}</code>
</td>
</tr>
</tbody>
</table>
</div>
<p className="py-1 font-medium text-sm">
<p className="py-1 text-sm font-medium">
<FontAwesomeIcon icon="exclamation-triangle" className="mr-1 text-yellow-400" /> If you see anything
missing or incorrect, you need to reconfigure <code className="text-xs font-mono">/config/api.json</code>{' '}
missing or incorrect, you need to reconfigure <code className="font-mono text-xs">/config/api.json</code>{' '}
and redeploy this instance.
</p>
<div className="text-right mb-2 mt-6">
<div className="mb-2 mt-6 text-right">
<button
className="text-white bg-gradient-to-r from-cyan-500 to-blue-500 hover:bg-gradient-to-bl focus:ring-4 focus:ring-cyan-300 dark:focus:ring-cyan-800 font-medium rounded-lg text-sm px-4 py-2.5 text-center"
className="rounded-lg bg-gradient-to-r from-cyan-500 to-blue-500 px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 focus:ring-cyan-300 dark:focus:ring-cyan-800"
onClick={() => {
router.push('/onedrive-vercel-index-oauth/step-2')
}}

View file

@ -20,16 +20,16 @@ export default function OAuthStep2() {
const oAuthUrl = generateAuthorisationUrl()
return (
<div className="dark:bg-gray-900 flex flex-col items-center justify-center min-h-screen bg-white">
<div className="flex min-h-screen flex-col items-center justify-center bg-white dark:bg-gray-900">
<Head>
<title>{`OAuth Step 2 - ${siteConfig.title}`}</title>
</Head>
<main className="bg-gray-50 dark:bg-gray-800 flex flex-col flex-1 w-full">
<main className="flex w-full flex-1 flex-col bg-gray-50 dark:bg-gray-800">
<Navbar />
<div className="w-full max-w-5xl p-4 mx-auto">
<div className="dark:bg-gray-900 dark:text-gray-100 bg-white rounded p-3">
<div className="mx-auto w-full max-w-5xl p-4">
<div className="rounded bg-white p-3 dark:bg-gray-900 dark:text-gray-100">
<div className="mx-auto w-52">
<Image
src="/images/fabulous-come-back-later.png"
@ -39,17 +39,17 @@ export default function OAuthStep2() {
priority
/>
</div>
<h3 className="font-medium text-xl mb-4 text-center">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="mb-4 text-center text-xl font-medium">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="font-medium text-lg mt-4 mb-2">Step 2/3: Get authorisation code</h3>
<h3 className="mt-4 mb-2 text-lg font-medium">Step 2/3: Get authorisation code</h3>
<p className="py-1 text-red-400 font-medium text-sm">
<p className="py-1 text-sm font-medium text-red-400">
<FontAwesomeIcon icon="exclamation-circle" className="mr-1" /> If you are not the owner of this website,
stop now, as continuing with this process may expose your personal files in OneDrive.
</p>
<div
className="relative my-2 font-mono border border-gray-500/50 rounded text-sm bg-gray-50 dark:bg-gray-800 cursor-pointer hover:opacity-80"
className="relative my-2 cursor-pointer rounded border border-gray-500/50 bg-gray-50 font-mono text-sm hover:opacity-80 dark:bg-gray-800"
onClick={() => {
window.open(oAuthUrl)
}}
@ -57,25 +57,25 @@ export default function OAuthStep2() {
<div className="absolute top-0 right-0 p-1 opacity-60">
<FontAwesomeIcon icon="external-link-alt" />
</div>
<pre className="p-2 whitespace-pre-wrap overflow-x-auto">
<pre className="overflow-x-auto whitespace-pre-wrap p-2">
<code>{oAuthUrl}</code>
</pre>
</div>
<p className="py-1">
The OAuth link for getting the authorisation code has been created. Click on the link above to get the{' '}
<b className="underline decoration-wavy decoration-yellow-400">authorisation code</b>. Your browser will
<b className="underline decoration-yellow-400 decoration-wavy">authorisation code</b>. Your browser will
open a new tab to Microsoft&apos;s account login page. After logging in and authenticating with your
Microsoft account, you will be redirected to a blank page on localhost. Paste{' '}
<b className="underline decoration-wavy decoration-teal-500">the entire redirected URL</b> down below.
<b className="underline decoration-teal-500 decoration-wavy">the entire redirected URL</b> down below.
</p>
<div className="my-4 rounded overflow-hidden w-2/3 mx-auto">
<div className="my-4 mx-auto w-2/3 overflow-hidden rounded">
<Image src="/images/step-2-screenshot.png" width={1466} height={607} alt="step 2 screenshot" />
</div>
<input
className={`w-full flex-1 border bg-gray-50 dark:bg-gray-800 dark:text-white focus:ring focus:outline-none p-2 font-mono rounded my-2 font-medium text-sm ${
className={`my-2 w-full flex-1 rounded border bg-gray-50 p-2 font-mono text-sm font-medium focus:outline-none focus:ring dark:bg-gray-800 dark:text-white ${
authCode
? 'border-green-500/50 focus:ring-green-500/30 dark:focus:ring-green-500/40'
: 'border-red-500/50 focus:ring-red-500/30 dark:focus:ring-red-500/40'
@ -91,7 +91,7 @@ export default function OAuthStep2() {
/>
<p className="py-1">The authorisation code extracted is:</p>
<p className="my-2 font-mono border border-gray-400/20 rounded text-sm bg-gray-50 dark:bg-gray-800 p-2 opacity-80 truncate overflow-hidden">
<p className="my-2 overflow-hidden truncate rounded border border-gray-400/20 bg-gray-50 p-2 font-mono text-sm opacity-80 dark:bg-gray-800">
{authCode || <span className="animate-pulse">Waiting for code...</span>}
</p>
@ -101,9 +101,9 @@ export default function OAuthStep2() {
: '❌ No valid code extracted.'}
</p>
<div className="text-right mb-2 mt-6">
<div className="mb-2 mt-6 text-right">
<button
className="text-white bg-gradient-to-br from-green-500 to-cyan-400 hover:bg-gradient-to-bl focus:ring-4 focus:ring-green-200 dark:focus:ring-green-800 font-medium rounded-lg text-sm px-4 py-2.5 text-center disabled:cursor-not-allowed disabled:grayscale"
className="rounded-lg bg-gradient-to-br from-green-500 to-cyan-400 px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 focus:ring-green-200 disabled:cursor-not-allowed disabled:grayscale dark:focus:ring-green-800"
disabled={authCode === ''}
onClick={() => {
setButtonLoading(true)
@ -112,7 +112,7 @@ export default function OAuthStep2() {
>
{buttonLoading ? (
<>
<span>Requesting tokens</span> <LoadingIcon className="animate-spin w-4 h-4 ml-1 inline" />
<span>Requesting tokens</span> <LoadingIcon className="ml-1 inline h-4 w-4 animate-spin" />
</>
) : (
<>

View file

@ -36,7 +36,7 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
setButtonError(false)
setButtonContent(
<div>
<span>Storing tokens</span> <LoadingIcon className="animate-spin w-4 h-4 ml-1 inline" />
<span>Storing tokens</span> <LoadingIcon className="ml-1 inline h-4 w-4 animate-spin" />
</div>
)
@ -84,16 +84,16 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
}
return (
<div className="dark:bg-gray-900 flex flex-col items-center justify-center min-h-screen bg-white">
<div className="flex min-h-screen flex-col items-center justify-center bg-white dark:bg-gray-900">
<Head>
<title>{`OAuth Step 3 - ${siteConfig.title}`}</title>
</Head>
<main className="bg-gray-50 dark:bg-gray-800 flex flex-col flex-1 w-full">
<main className="flex w-full flex-1 flex-col bg-gray-50 dark:bg-gray-800">
<Navbar />
<div className="w-full max-w-5xl p-4 mx-auto">
<div className="dark:bg-gray-900 dark:text-gray-100 bg-white rounded p-3">
<div className="mx-auto w-full max-w-5xl p-4">
<div className="rounded bg-white p-3 dark:bg-gray-900 dark:text-gray-100">
<div className="mx-auto w-52">
<Image
src="/images/fabulous-celebration.png"
@ -103,16 +103,16 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
priority
/>
</div>
<h3 className="font-medium text-xl mb-4 text-center">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="mb-4 text-center text-xl font-medium">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="font-medium text-lg mt-4 mb-2">Step 3/3: Get access and refresh tokens</h3>
<h3 className="mt-4 mb-2 text-lg font-medium">Step 3/3: Get access and refresh tokens</h3>
{error ? (
<div>
<p className="text-red-500 py-1 font-medium">
<p className="py-1 font-medium text-red-500">
<FontAwesomeIcon icon="exclamation-circle" className="mr-2" />
<span>Whoops, looks like we got a problem: {error}.</span>
</p>
<p className="my-2 font-mono border border-gray-400/20 rounded text-sm bg-gray-50 dark:bg-gray-800 p-2 opacity-80 whitespace-pre-line">
<p className="my-2 whitespace-pre-line rounded border border-gray-400/20 bg-gray-50 p-2 font-mono text-sm opacity-80 dark:bg-gray-800">
{description}
</p>
{errorUri && (
@ -122,16 +122,16 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
href={errorUri}
target="_blank"
rel="noopener noreferrer"
className="hover:underline text-blue-600 dark:text-blue-500"
className="text-blue-600 hover:underline dark:text-blue-500"
>
Microsoft&apos;s official explanation
</a>{' '}
on the error message.
</p>
)}
<div className="text-right mb-2 mt-6">
<div className="mb-2 mt-6 text-right">
<button
className="text-white bg-gradient-to-br from-red-500 to-orange-400 hover:bg-gradient-to-bl focus:ring-4 focus:ring-red-200 dark:focus:ring-red-800 font-medium rounded-lg text-sm px-4 py-2.5 text-center disabled:cursor-not-allowed disabled:grayscale"
className="rounded-lg bg-gradient-to-br from-red-500 to-orange-400 px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 focus:ring-red-200 disabled:cursor-not-allowed disabled:grayscale dark:focus:ring-red-800"
onClick={() => {
router.push('/onedrive-vercel-index-oauth/step-1')
}}
@ -149,7 +149,7 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
<FontAwesomeIcon icon={['far', 'check-circle']} className="text-green-500" />{' '}
<span>
Acquired access_token:{' '}
<code className="text-sm font-mono opacity-80">{`${accessToken.substring(0, 60)}...`}</code>
<code className="font-mono text-sm opacity-80">{`${accessToken.substring(0, 60)}...`}</code>
</span>
</li>
)}
@ -158,13 +158,13 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
<FontAwesomeIcon icon={['far', 'check-circle']} className="text-green-500" />{' '}
<span>
Acquired refresh_token:{' '}
<code className="text-sm font-mono opacity-80">{`${refreshToken.substring(0, 60)}...`}</code>
<code className="font-mono text-sm opacity-80">{`${refreshToken.substring(0, 60)}...`}</code>
</span>
</li>
)}
</ol>
<p className="py-1 font-medium text-sm text-teal-500">
<p className="py-1 text-sm font-medium text-teal-500">
<FontAwesomeIcon icon="exclamation-circle" className="mr-1" /> These tokens may take a few seconds to
populate after you click the button below. If you go back home and still see the welcome page telling
you to re-authenticate, revisit home and do a hard refresh.
@ -176,9 +176,9 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
and updates after your site goes live.
</p>
<div className="text-right mb-2 mt-6">
<div className="mb-2 mt-6 text-right">
<button
className={`text-white bg-gradient-to-br hover:bg-gradient-to-bl focus:ring-4 font-medium rounded-lg text-sm px-4 py-2.5 text-center ${
className={`rounded-lg bg-gradient-to-br px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 ${
buttonError
? 'from-red-500 to-orange-400 focus:ring-red-200 dark:focus:ring-red-800'
: 'from-green-500 to-teal-300 focus:ring-green-200 dark:focus:ring-green-800'

View file

@ -24,11 +24,14 @@ specifiers:
emoji-regex: ^10.0.0
eslint: 8.8.0
eslint-config-next: 12.0.10
eslint-config-prettier: ^8.3.0
ioredis: ^4.28.2
jszip: ^3.7.1
next: ^12.0.10
nextjs-progressbar: ^0.0.13
postcss: ^8.4.5
prettier: ^2.5.1
prettier-plugin-tailwindcss: ^0.1.4
preview-office-docs: ^1.0.2
prismjs: ^1.23.0
react: ^17.0.2
@ -102,7 +105,10 @@ devDependencies:
autoprefixer: 10.4.2_postcss@8.4.6
eslint: 8.8.0
eslint-config-next: 12.0.10_9534215cc73b6f260bf33f1b86e3ae0e
eslint-config-prettier: 8.3.0_eslint@8.8.0
postcss: 8.4.6
prettier: 2.5.1
prettier-plugin-tailwindcss: 0.1.4_prettier@2.5.1
tailwindcss: 3.0.18_833e1018ad0d7954aa80c53675939269
typescript: 4.5.5
@ -1228,6 +1234,15 @@ packages:
- supports-color
dev: true
/eslint-config-prettier/8.3.0_eslint@8.8.0:
resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
dependencies:
eslint: 8.8.0
dev: true
/eslint-import-resolver-node/0.3.6:
resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==}
dependencies:
@ -2875,6 +2890,20 @@ packages:
engines: {node: '>= 0.8.0'}
dev: true
/prettier-plugin-tailwindcss/0.1.4_prettier@2.5.1:
resolution: {integrity: sha512-kt3YFWqxcG9+bilBI0hPF7RjQZNtgBRvjJZGw6B2MNAjPqlfcYIiZnNaIEnq4XimKLTzZYxz6jQnUXmSQ/5njg==}
peerDependencies:
prettier: '>=2.2.0'
dependencies:
prettier: 2.5.1
dev: true
/prettier/2.5.1:
resolution: {integrity: sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==}
engines: {node: '>=10.13.0'}
hasBin: true
dev: true
/preview-office-docs/1.0.2_react@17.0.2:
resolution: {integrity: sha512-dVss4jWfVgZJcVskbOPV5ifpFokRYY1ZW54Z6DvwCg/HzNqq8rZw8yVM+nJAFmcFz6Zy7aY9n1/KhPDkm+Ky6Q==}
engines: {node: '>=10'}