Skip to content

Commit

Permalink
feature: add support for OneDrive
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksey-hoffman committed Sep 1, 2021
1 parent 4b3dd1b commit 574787c
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 21 deletions.
6 changes: 6 additions & 0 deletions src/appPaths.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const pictures = getUserDirPath('pictures')
const screenshots = getUserDirPath('screenshots')
const videos = getUserDirPath('videos')
const music = getUserDirPath('music')
const oneDrive = getUserDirPath('oneDrive')

const userDataRoot = PATH.parse(userData).root.replace(/\\/g, '/')
const resources = process.env.NODE_ENV === 'production'
Expand Down Expand Up @@ -154,6 +155,7 @@ const appPaths = {
screenshots,
videos,
music,
oneDrive,
binCompressed,
resourcesBin,
bin,
Expand All @@ -174,6 +176,10 @@ function getUserDirPath (dirName) {
return pictures
}
}
else if (dirName === 'oneDrive') {
return env.OneDrive
}

try {
return electronRemote.app.getPath(dirName)
}
Expand Down
31 changes: 22 additions & 9 deletions src/components/BasicItemCardIterator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,32 +80,45 @@ Copyright © 2021 - present Aleksey Hoffman. All rights reserved.
class="basic-item-card__thumb__inner"
v-if="type === 'drive'"
>
<div v-if="!driveCardShowProgress || driveCardProgressType !== 'circular'">
<template v-if="!driveCardShowProgress || driveCardProgressType !== 'circular'">
<v-icon
class="basic-item-card__icon mt-1"
size="22px"
>{{getThumbIcon(item)}}
:size="$utils.getDriveIcon(item).size"
>{{$utils.getDriveIcon(item).icon}}
</v-icon>
<div class="basic-item-card__progress--circular__text">
<div
class="basic-item-card__progress__text"
v-if="item.percentUsed"
>
{{item.percentUsed}}%
</div>
</div>
</template>

<div
<template
class="basic-item-card__progress--circular"
v-show="driveCardShowProgress && driveCardProgressType === 'circular'"
v-if="driveCardShowProgress && driveCardProgressType === 'circular'"
>
<v-icon
class="basic-item-card__icon mt-1"
v-if="!item.percentUsed"
:size="$utils.getDriveIcon(item).size"
>{{$utils.getDriveIcon(item).icon}}
</v-icon>
<v-progress-circular
v-if="item.percentUsed"
:value="`${item.percentUsed}`"
size="40"
width="2"
:color="getStorageBarColor({item, type: 'circular'})"
>
<div class="basic-item-card__progress--circular__text">
<div
class="basic-item-card__progress__text"
v-if="item.percentUsed"
>
{{item.percentUsed}}%
</div>
</v-progress-circular>
</div>
</template>
</div>
</div>

Expand Down
22 changes: 21 additions & 1 deletion src/components/DirItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,23 @@ Copyright © 2021 - present Aleksey Hoffman. All rights reserved.
<div
v-else-if="type === 'file' || type === 'file-symlink'"
class="dir-item-card__item-count"
>{{$utils.prettyBytes(source.stat.size, 1)}}
>
{{$utils.prettyBytes(source.stat.size, 1)}}

<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-icon
class="ml-2"
v-on="on"
v-show="isOffline"
color="var(--color-6)"
size="12px"
>
mdi-cloud-outline
</v-icon>
</template>
<span>Offline item (size on drive is 0)</span>
</v-tooltip>
</div>
</template>

Expand Down Expand Up @@ -324,6 +340,10 @@ export default {
return this.layout
? this.layout
: this.navigatorLayout
},
isOffline () {
let isOfflineFile = this.source.sizeOnDisk === 0 && !this.source.type.includes('directory')
return isOfflineFile
}
},
methods: {
Expand Down
12 changes: 7 additions & 5 deletions src/components/InfoPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,20 @@ Copyright © 2021 - present Aleksey Hoffman. All rights reserved.
<div class="info-panel__preview-container__media-container">
<img
class="fade-in-1s info-panel__preview-container__media"
v-if="showPreviewItem('image') && !selectedDirItemData.itemProps.isInaccessible"
v-if="showPreviewItem('image')"
:src="previewMediaSrc"
>
<audio
class="fade-in-1s info-panel__preview-container__media"
v-if="showPreviewItem('audio') && !selectedDirItemData.itemProps.isInaccessible"
v-if="showPreviewItem('audio')"
:src="previewMediaSrc"
controls
preload="metadata"
style="display: none"
/>
<video
class="fade-in-1s info-panel__preview-container__media"
v-if="showPreviewItem('video') && !selectedDirItemData.itemProps.isInaccessible"
v-if="showPreviewItem('video')"
:src="previewMediaSrc"
controls
preload="metadata"
Expand Down Expand Up @@ -359,8 +359,10 @@ export default {
}
},
showPreviewItem (mediaType) {
const itemMime = this.selectedDirItemData.mimeDescription
return itemMime === mediaType
const itemMime = this.selectedDirItemData?.mimeDescription
const isInaccessible = this.selectedDirItemData?.itemProps?.isInaccessible
const itemIsOffline = this.selectedDirItemData?.itemProps?.sizeOnDisk === 0
return (itemMime === mediaType) && !isInaccessible && !itemIsOffline
},
delayInfoPanel () {
if (this.navigatorViewInfoPanel) {
Expand Down
24 changes: 18 additions & 6 deletions src/components/NavigationPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,31 @@ Copyright © 2021 - present Aleksey Hoffman. All rights reserved.
<template v-slot:activator="{ on }">
<v-layout
v-on="on"
@click="$store.dispatch('OPEN_DIR_ITEM_FROM_PATH', drive.mount)"
@click="$store.dispatch('OPEN_DIR_ITEM_FROM_PATH', drive.path)"
class="nav-panel__item"
align-center v-ripple
>
<div class="nav-panel__item__indicator"></div>
<div class="nav-panel__item__icon-container">
<v-icon size="20px" class="nav-panel__item__icon">
{{drive.removable ? 'fab fa-usb' : 'far fa-hdd'}}
<v-icon
class="nav-panel__item__icon"
:size="$utils.getDriveIcon(drive).size"
>
{{$utils.getDriveIcon(drive).icon}}
</v-icon>
</div>
<transition name="slide-fade-left">
<div v-if="!navigationPanelMiniVariant">
<div class="nav-panel__item__title mb-1">
<div
class="nav-panel__item__title"
v-if="drive.type === 'cloud'"
>
{{drive.titleSummary}}
</div>
<div
class="nav-panel__item__title mb-1"
v-else
>
<v-layout align-center>
<div class="nav-panel__item__title__mount">
<span
Expand All @@ -147,10 +159,10 @@ Copyright © 2021 - present Aleksey Hoffman. All rights reserved.
</div>
<v-spacer></v-spacer>
<div class="caption">
{{$utils.prettyBytes(drive.size.free, 1)}} left
{{drive.size.free && $utils.prettyBytes(drive.size.free, 1)}} left
</div>
</v-layout>
<div>
<div v-if="drive.percentUsed">
<v-progress-linear
:value="`${drive.percentUsed}`"
height="4"
Expand Down
70 changes: 70 additions & 0 deletions src/utils/fsInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// License: GNU GPLv3 or later. See the license file in the project root for more information.
// Copyright © 2021 - present Aleksey Hoffman. All rights reserved.

const fswin = require('fswin')
const PATH = require('path')
const fs = require('fs')

async function getDirSize (path) {
const trammelGetSize = require('trammel')

return await new Promise((resolve, reject) => {
const options = {type: 'raw', stopOnError: false}
trammelGetSize(path, options, (error, size) => {
if (error) {reject(error)}
resolve(size)
})
})
}

async function getDirSizeOnDisk (dir) {
return new Promise((resolve, reject) => {
let paths = getFilesRecursively(dir)
let totalSize = 0
let promises = []
paths.forEach(path => {
promises.push(new Promise((resolve) => {
fswin.ntfs.getCompressedSize(path, (size) => {
resolve(size)
})
}))
})

Promise.allSettled(promises)
.then((data) => {
data.forEach(promise => {
totalSize += promise.value
})
resolve(totalSize)
})
})
}

function getFilesRecursively (dir) {
let files = []

const walk = (dir) => {
const filesInDirectory = fs.readdirSync(dir)
for (const file of filesInDirectory) {
const absolute = PATH.join(dir, file)
try {
if (fs.statSync(absolute).isDirectory()) {
walk(absolute)
}
else {
files.push(absolute)
}
}
catch (error) {}
}
}
walk(dir)

return files
}

module.exports = {
getDirSize,
getDirSizeOnDisk
}
28 changes: 28 additions & 0 deletions src/utils/navigatorCore.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,32 @@ function shouldFetchExtraStats (path) {
return isExtraStatsEmpty && !isExtraStatsFetchInProgress && isExtraStatsForCurrentDir
}

function getAttributes (dirItemData) {
if (utils.platform === 'win32') {
return fsWin.getAttributesSync(dirItemData.path)
}
// TODO: FINISH
else if (utils.platform === 'linux') {
return {}
}
else if (utils.platform === 'darwin') {
return 0
}
}

function getSizeOnDisk (dirItemData) {
if (utils.platform === 'win32') {
return fsWin.ntfs.getCompressedSizeSync(dirItemData.path)
}
// TODO: FINISH
else if (utils.platform === 'linux') {
return {}
}
else if (utils.platform === 'darwin') {
return 0
}
}

/**
* @param {string} path
* @param {string} nameBase
Expand Down Expand Up @@ -302,6 +328,8 @@ async function fetchDirItemData (path, nameBase, itemHeight) {
dirItemData.stat = await getStat(path)
// if (isObjectEmpty(dirItemData.stat)) {throw Error('inaccessible item')}
// console.log(dirItemData.path, isObjectEmpty(dirItemData.stat))
dirItemData.attributes = getAttributes(dirItemData)
dirItemData.sizeOnDisk = getSizeOnDisk(dirItemData)
dirItemData.isHidden = isHidden(dirItemData)
dirItemData.isInaccessible = isObjectEmpty(dirItemData.stat)
dirItemData.isWin32Shortcut = await isFile(dirItemData, dirItemData.stat) && nameBase.endsWith('.lnk')
Expand Down
27 changes: 27 additions & 0 deletions src/utils/storageInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
import utils from './utils'
import * as fsManager from './fsManager.js'

const fs = require('fs')
const PATH = require('path')
const sysInfo = require('systeminformation')
const diskusage = require('diskusage')
const fsInfo = require('./fsInfo.js')
const appPaths = require('../appPaths.js')

let state = {
extraDeviceData: [],
Expand All @@ -34,8 +37,10 @@ let state = {
export async function getStorageDevices () {
try {
let blockDevices = await getBlockDevices()
let oneDrive = await getOneDrive()
let storageDevices = [
...blockDevices,
...oneDrive
]
state.previousDriveList = [...state.driveList]
state.driveList = blockDevices
Expand All @@ -55,6 +60,28 @@ function handleDriveListChange () {
}
}

async function getOneDrive () {
let path = appPaths.oneDrive
if (path) {
let oneDriveItemList = await fs.promises.readdir(path)
let size = await fsInfo.getDirSize(path)
let sizeOnDisk = await fsInfo.getDirSizeOnDisk(path)
let formattedSizeOnDisk = utils.prettyBytes(sizeOnDisk, 1)
let formattedSizeTotal = utils.prettyBytes(size, 1)
return [{
type: 'cloud',
path,
mount: path,
infoSummary: `Used: ${formattedSizeTotal} • Locally: ${formattedSizeOnDisk}`,
titleSummary: 'OneDrive',
isEmpty: oneDriveItemList.length === 0
}]
}
else {
return []
}
}

export async function fetchBlockDevicesExtraData () {
try {
getBlockDevicesExtraData()
Expand Down

0 comments on commit 574787c

Please sign in to comment.