Skip to content

Commit

Permalink
Merge pull request #41308 from nextcloud/artonge/feat/live_photos
Browse files Browse the repository at this point in the history
Customize rendering for live photos
  • Loading branch information
artonge authored Nov 9, 2023
2 parents 397c969 + dc00904 commit 1fe951f
Show file tree
Hide file tree
Showing 72 changed files with 178 additions and 103 deletions.
7 changes: 7 additions & 0 deletions apps/dav/lib/Connector/Sabre/FilesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class FilesPlugin extends ServerPlugin {
public const SUBFOLDER_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-folder-count';
public const SUBFILE_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-file-count';
public const FILE_METADATA_PREFIX = '{http://nextcloud.org/ns}metadata-';
public const HIDDEN_PROPERTYNAME = '{http://nextcloud.org/ns}hidden';

/** Reference to main server object */
private ?Server $server = null;
Expand Down Expand Up @@ -386,6 +387,12 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
$propFind->handle(self::FILE_METADATA_PREFIX . $metadataKey, $metadataValue);
}

$propFind->handle(self::HIDDEN_PROPERTYNAME, function () use ($node) {
$filesMetadataManager = \OCP\Server::get(IFilesMetadataManager::class);
$metadata = $filesMetadataManager->getMetadata((int)$node->getFileId(), true);
return $metadata->hasKey('files-live-photo') && $node->getFileInfo()->getMimetype() === 'video/quicktime' ? 'true' : 'false';
});

/**
* Return file/folder name as displayname. The primary reason to
* implement it this way is to avoid costly fallback to
Expand Down
14 changes: 14 additions & 0 deletions apps/files/src/components/FileEntry/FileEntryPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
:aria-label="t('files', 'Favorite')">
<FavoriteIcon v-once />
</span>

<OverlayIcon :is="fileOverlay"
v-if="fileOverlay"
class="files-list__row-icon-overlay" />
</span>
</template>

Expand All @@ -71,9 +75,11 @@ import KeyIcon from 'vue-material-design-icons/Key.vue'
import LinkIcon from 'vue-material-design-icons/Link.vue'
import NetworkIcon from 'vue-material-design-icons/Network.vue'
import TagIcon from 'vue-material-design-icons/Tag.vue'
import PlayCircleIcon from 'vue-material-design-icons/PlayCircle.vue'

import { useUserConfigStore } from '../../store/userconfig.ts'
import FavoriteIcon from './FavoriteIcon.vue'
import { isLivePhoto } from '../../services/LivePhotos'

export default Vue.extend({
name: 'FileEntryPreview',
Expand Down Expand Up @@ -163,6 +169,14 @@ export default Vue.extend({
}
},

fileOverlay() {
if (isLivePhoto(this.source)) {
return PlayCircleIcon
}

return null
},

folderOverlay() {
if (this.source.type !== FileType.Folder) {
return null
Expand Down
16 changes: 14 additions & 2 deletions apps/files/src/components/FilesListVirtual.vue
Original file line number Diff line number Diff line change
Expand Up @@ -510,14 +510,26 @@ export default Vue.extend({
right: -10px;
}

// Folder overlay
// File and folder overlay
&-overlay {
position: absolute;
max-height: calc(var(--icon-preview-size) * 0.5);
max-width: calc(var(--icon-preview-size) * 0.5);
color: var(--color-main-background);
color: var(--color-main-text);
// better alignment with the folder icon
margin-top: 2px;

svg {
border-radius: 100%;

// Sow a border around the icon for better contrast
path {
stroke: var(--color-main-background);
stroke-width: 8px;
stroke-linejoin: round;
paint-order: stroke;
}
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion apps/files/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
*/
import MenuIcon from '@mdi/svg/svg/sun-compass.svg?raw'
import { FileAction, addNewFileMenuEntry, registerFileAction } from '@nextcloud/files'
import { FileAction, addNewFileMenuEntry, registerDavProperty, registerFileAction } from '@nextcloud/files'

import { action as deleteAction } from './actions/deleteAction'
import { action as downloadAction } from './actions/downloadAction'
Expand All @@ -41,6 +41,8 @@ import registerPreviewServiceWorker from './services/ServiceWorker.js'

import './init-templates'

import { initLivePhotos } from './services/LivePhotos'

// Register file actions
registerFileAction(deleteAction)
registerFileAction(downloadAction)
Expand All @@ -63,3 +65,7 @@ registerRecentView()

// Register preview service worker
registerPreviewServiceWorker()

registerDavProperty('nc:hidden', { nc: 'http://nextcloud.org/ns' })

initLivePhotos()
33 changes: 33 additions & 0 deletions apps/files/src/services/LivePhotos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @copyright Copyright (c) 2023 Louis Chmn <louis@chmn.me>
*
* @author Louis Chmn <louis@chmn.me>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { Node, registerDavProperty } from '@nextcloud/files'

export function initLivePhotos(): void {
registerDavProperty('nc:metadata-files-live-photo', { nc: 'http://nextcloud.org/ns' })
}

/**
* @param {Node} node - The node
*/
export function isLivePhoto(node: Node): boolean {
return node.attributes['metadata-files-live-photo'] !== undefined
}
5 changes: 4 additions & 1 deletion apps/files/src/views/FilesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,10 @@ export default Vue.extend({
},

dirContents(): Node[] {
return (this.currentFolder?._children || []).map(this.getNode).filter(file => file)
return (this.currentFolder?._children || [])
.map(this.getNode)
.filter(file => file)
.filter(file => file?.attributes?.hidden !== true)
},

/**
Expand Down
4 changes: 2 additions & 2 deletions dist/9064-9064.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/9064-9064.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/comments-comments-app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/comments-comments-app.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/core-login.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/core-login.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/core-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/core-main.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/core-profile.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/core-profile.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/core-unified-search.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/core-unified-search.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/dav-settings-personal-availability.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/dav-settings-personal-availability.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/federatedfilesharing-vue-settings-admin.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/federatedfilesharing-vue-settings-admin.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/federatedfilesharing-vue-settings-personal.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/federatedfilesharing-vue-settings-personal.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files-init.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-init.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-main.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files-personal-settings.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-personal-settings.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files-reference-files.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-reference-files.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files-sidebar.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-sidebar.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files_external-init.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files_external-init.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files_reminders-init.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files_reminders-init.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files_sharing-files_sharing_tab.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files_sharing-files_sharing_tab.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files_sharing-personal-settings.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files_sharing-personal-settings.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files_versions-files_versions.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files_versions-files_versions.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-admin-basic-settings.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-admin-basic-settings.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-admin-delegation.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-admin-delegation.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-admin-security.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-admin-security.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-apps-users-management.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-apps-users-management.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-personal-info.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-personal-info.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-personal-password.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-personal-password.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-personal-security.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-personal-security.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/sharebymail-vue-settings-admin-sharebymail.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/sharebymail-vue-settings-admin-sharebymail.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/theming-admin-theming.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/theming-admin-theming.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/theming-personal-theming.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/theming-personal-theming.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/updatenotification-updatenotification.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/updatenotification-updatenotification.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/user_status-menu.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/user_status-menu.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/weather_status-weather-status.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/weather_status-weather-status.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/workflowengine-workflowengine.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/workflowengine-workflowengine.js.map

Large diffs are not rendered by default.

0 comments on commit 1fe951f

Please sign in to comment.