folder-share: tweaks

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/888/head
Varun Patil 2023-10-19 22:32:34 -07:00
parent 3d8ad4d668
commit 3575c0b166
8 changed files with 51 additions and 24 deletions

View File

@ -81,6 +81,7 @@ class PublicAlbumController extends Controller
// Share info // Share info
$this->initialState->provideInitialState('share_title', $album['name']); $this->initialState->provideInitialState('share_title', $album['name']);
$this->initialState->provideInitialState('share_type', 'album');
// Render main template // Render main template
$response = new PublicTemplateResponse(Application::APPNAME, 'main', PageController::getMainParams()); $response = new PublicTemplateResponse(Application::APPNAME, 'main', PageController::getMainParams());

View File

@ -98,15 +98,18 @@ class PublicController extends AuthPublicShareController
// Scripts // Scripts
\OCP\Util::addScript(Application::APPNAME, 'memories-main'); \OCP\Util::addScript(Application::APPNAME, 'memories-main');
// Get share node
$node = $share->getNode();
// Share info // Share info
$this->initialState->provideInitialState('no_download', $share->getHideDownload()); $this->initialState->provideInitialState('no_download', $share->getHideDownload());
$this->initialState->provideInitialState('share_title', $node->getName());
// Share file id only if not a folder
$node = $share->getNode();
if ($node instanceof \OCP\Files\File) { if ($node instanceof \OCP\Files\File) {
$this->initialState->provideInitialState('single_item', $this->getSingleItemInitialState($node)); $this->initialState->provideInitialState('single_item', $this->getSingleItemInitialState($node));
$this->initialState->provideInitialState('share_type', 'file');
} elseif ($node instanceof \OCP\Files\Folder) { } elseif ($node instanceof \OCP\Files\Folder) {
$this->initialState->provideInitialState('share_title', $node->getName()); $this->initialState->provideInitialState('share_type', 'folder');
} else { } else {
throw new NotFoundException(); throw new NotFoundException();
} }

View File

@ -84,17 +84,24 @@ class FsManager
throw new \Exception('Share is not a folder'); throw new \Exception('Share is not a folder');
} }
// Folder inside shared folder
if ($path = $this->getRequestFolder()) { if ($path = $this->getRequestFolder()) {
$sanitized = Util::sanitizePath($path);
if (null === $sanitized) {
throw new \Exception("Invalid parameter path: {$path}");
}
// Get subnode from share
try { try {
$node = $share->get(Util::sanitizePath($path)); $share = $share->get($sanitized);
} catch (\OCP\Files\NotFoundException $e) { } catch (\OCP\Files\NotFoundException $e) {
throw new \Exception("Folder not found: {$e->getMessage()}"); throw new \Exception("Folder not found: {$e->getMessage()}");
} }
$root->addFolder($node);
} else {
$root->addFolder($share);
} }
// This internally checks if the node is a folder
$root->addFolder($share);
return $root; return $root;
} }
@ -331,6 +338,9 @@ class FsManager
return $share; return $share;
} }
/**
* Get the share node from the request.
*/
public function getShareNode(): ?Node public function getShareNode(): ?Node
{ {
$share = $this->getShareObject(); $share = $this->getShareObject();

View File

@ -58,15 +58,15 @@ export default defineComponent({
computed: { computed: {
/** Open folder */ /** Open folder */
target() { target() {
let currentPath: string[] | string = this.$route.params.path || []; let path: string[] | string = this.$route.params.path || [];
if (typeof currentPath === 'string') { if (typeof path === 'string') {
currentPath = currentPath.split('/'); path = path.split('/');
} }
return { return {
name: this.$route.name, name: this.$route.name,
params: { params: {
path: [...currentPath, this.data.name], path: [...path, this.data.name],
}, },
}; };
}, },

View File

@ -15,9 +15,11 @@ import FolderDynamicTopMatter from './FolderDynamicTopMatter.vue';
import PlacesDynamicTopMatterVue from './PlacesDynamicTopMatter.vue'; import PlacesDynamicTopMatterVue from './PlacesDynamicTopMatter.vue';
import OnThisDay from './OnThisDay.vue'; import OnThisDay from './OnThisDay.vue';
import * as PublicShareHeader from './PublicShareHeader';
import * as strings from '../../services/strings'; import * as strings from '../../services/strings';
// Auto-hide top header on public shares if redundant
import './PublicShareHeader';
export default defineComponent({ export default defineComponent({
name: 'DynamicTopMatter', name: 'DynamicTopMatter',
@ -50,17 +52,18 @@ export default defineComponent({
viewName(): string { viewName(): string {
// Show album name for album view // Show album name for album view
if (this.routeIsAlbums) { if (this.routeIsAlbums) {
return this.$route.params.name || ''; return this.$route.params.name || String();
} }
// Show share name for public shares, except for folder share, because the name is already present in the breadcrumbs // Show share name for public shares, except for folder share,
// because the name is already present in the breadcrumbs
if (this.routeIsPublic && !this.routeIsFolderShare) { if (this.routeIsPublic && !this.routeIsFolderShare) {
return PublicShareHeader.title; return this.initstate.shareTitle;
} }
// Only static top matter for these routes // Only static top matter for these routes
if (this.routeIsTags || this.routeIsPeople || this.routeIsPlaces) { if (this.routeIsTags || this.routeIsPeople || this.routeIsPlaces) {
return ''; return String();
} }
return strings.viewName(this.$route.name!); return strings.viewName(this.$route.name!);

View File

@ -2,10 +2,15 @@
<div class="top-matter"> <div class="top-matter">
<NcBreadcrumbs> <NcBreadcrumbs>
<NcBreadcrumb :title="rootFolderName" :to="{ name: $route.name }"> <NcBreadcrumb :title="rootFolderName" :to="{ name: $route.name }">
<template v-if="routeIsPublic" #icon> <template #icon>
<template v-if="routeIsPublic">
<ShareIcon :size="20" /> <ShareIcon :size="20" />
<span class="share-name">{{ rootFolderName }}</span> <span class="share-name">{{ rootFolderName }}</span>
</template> </template>
<template v-else>
<HomeIcon :size="20" />
</template>
</template>
</NcBreadcrumb> </NcBreadcrumb>
<NcBreadcrumb <NcBreadcrumb
v-for="folder in list" v-for="folder in list"
@ -48,8 +53,8 @@ import NcActions from '@nextcloud/vue/dist/Components/NcActions';
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton'; import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton';
import * as utils from '../../services/utils'; import * as utils from '../../services/utils';
import * as PublicShareHeader from './PublicShareHeader';
import HomeIcon from 'vue-material-design-icons/Home.vue';
import ShareIcon from 'vue-material-design-icons/ShareVariant.vue'; import ShareIcon from 'vue-material-design-icons/ShareVariant.vue';
import TimelineIcon from 'vue-material-design-icons/ImageMultiple.vue'; import TimelineIcon from 'vue-material-design-icons/ImageMultiple.vue';
import FoldersIcon from 'vue-material-design-icons/FolderMultiple.vue'; import FoldersIcon from 'vue-material-design-icons/FolderMultiple.vue';
@ -62,6 +67,7 @@ export default defineComponent({
NcBreadcrumb, NcBreadcrumb,
NcActions, NcActions,
NcActionButton, NcActionButton,
HomeIcon,
ShareIcon, ShareIcon,
TimelineIcon, TimelineIcon,
FoldersIcon, FoldersIcon,
@ -93,7 +99,7 @@ export default defineComponent({
}, },
rootFolderName(): string { rootFolderName(): string {
return this.routeIsPublic ? PublicShareHeader.title : 'Home'; return this.routeIsPublic ? this.initstate.shareTitle : this.t('memories', 'Home');
}, },
}, },
@ -120,7 +126,7 @@ export default defineComponent({
min-width: 0; min-width: 0;
height: unset; height: unset;
.share-name { .share-name {
margin-left: 1em; margin-left: 0.75em;
} }
} }
} }

View File

@ -1,10 +1,13 @@
import * as utils from '../../services/utils'; import * as utils from '../../services/utils';
// Shown in dynamic top matter (Timeline::viewName) // Shown in dynamic top matter (Timeline::viewName)
export const title = utils.initstate.shareTitle; const title = utils.initstate.shareTitle;
// Hide on album shares only
const hide = utils.initstate.shareType === 'album';
// Set up hook to monitor recycler scroll to show/hide header // Set up hook to monitor recycler scroll to show/hide header
if (title) { if (title && hide) {
const header = document.querySelector('header#header .header-appname') as HTMLElement; const header = document.querySelector('header#header .header-appname') as HTMLElement;
let isHidden = false; // cache state to avoid unnecessary DOM updates let isHidden = false; // cache state to avoid unnecessary DOM updates

View File

@ -22,6 +22,7 @@ export const constants = Object.freeze({
export const initstate = Object.freeze({ export const initstate = Object.freeze({
noDownload: loadState('memories', 'no_download', false) !== false, noDownload: loadState('memories', 'no_download', false) !== false,
shareTitle: loadState('memories', 'share_title', '') as string, shareTitle: loadState('memories', 'share_title', '') as string,
shareType: loadState('memories', 'share_type', null) as 'file' | 'folder' | 'album' | null,
singleItem: loadState('memories', 'single_item', null) as IPhoto | null, singleItem: loadState('memories', 'single_item', null) as IPhoto | null,
}); });