Compare commits

...

23 Commits

Author SHA1 Message Date
nextcloud-command c28f76b57a chore(deps): fix npm audit
Signed-off-by: GitHub <noreply@github.com>
2023-12-10 03:30:29 +00:00
Pytal 38f560b73a
Merge pull request #2183 from nextcloud/enh/a11y/app-nav-label
enh: Add navigation label
2023-12-06 18:37:27 -08:00
nextcloud-command a045d6d4bd chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2023-12-07 02:12:55 +00:00
Nextcloud bot 78d58a8bdb
Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2023-12-07 01:18:21 +00:00
Christopher Ng d048104ffe enh: Add navigation label
Signed-off-by: Christopher Ng <chrng8@gmail.com>
2023-12-06 16:51:28 -08:00
Louis 559933fc05
Merge pull request #2182 from nextcloud/artonge/fix/checkbox_layout
Fix checkbox layout
2023-12-07 01:39:12 +01:00
Louis Chemineau 5f6725af9f
chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
Signed-off-by: Louis Chemineau <louis@chmn.me>
2023-12-06 18:41:57 +01:00
Louis Chemineau b862e8e77a
Fix checkbox layout
Signed-off-by: Louis Chemineau <louis@chmn.me>
2023-12-06 18:41:57 +01:00
Louis 334f080ab3
Merge pull request #2175 from nextcloud/enh/noid/show-inline
show title and close of modal inline
2023-12-06 15:53:28 +01:00
nextcloud-command 8f1196e912 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2023-12-06 14:05:57 +00:00
Simon L 46fb961f0d show title and close of modal inline
Signed-off-by: Simon L <szaimen@e.mail.de>
2023-12-05 13:52:32 +01:00
Joas Schilling afaffd823b
Merge pull request #2171 from nextcloud/bugfix/noid/fix-is-not-null-queries
fix(DB): Fix "IS NOT NULL" database queries
2023-12-04 21:20:02 +01:00
Joas Schilling d836e048a9
fix(DB): Fix "IS NOT NULL" database queries
Signed-off-by: Joas Schilling <coding@schilljs.com>
2023-12-04 13:11:52 +01:00
Julius Härtl aa82646be1
Merge pull request #2166 from nextcloud/bugfix/skip-empty-files
fix: Skip empty files in metadata providers
2023-12-04 10:49:34 +01:00
Git'Fellow 7c09d26797
Merge pull request #2163 from nextcloud/dontCheckOnNull
Don't check display name on null
2023-12-04 10:17:33 +01:00
Julius Härtl 2eb4b83f99
fix: Skip empty files in metadata providers
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2023-12-04 08:42:20 +01:00
Nextcloud bot edceea6ccb
Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2023-12-04 01:16:21 +00:00
Marcel Klehr 6e49882de9
Merge pull request #2007 from nextcloud/fix/specialchars-in-face-names
Fix links to faces with special chars
2023-12-03 11:37:15 +01:00
nextcloud-command 987056c7c7 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2023-12-03 10:25:43 +00:00
Marcel Klehr 4f28927242 Fix links to faces with special chars
fixes #1886

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2023-12-03 11:21:49 +01:00
Git'Fellow f27fee79a6
Merge pull request #1897 from joshtrichards/jr-photos-addons
Add link to Recognize app in README
2023-12-03 10:25:47 +01:00
Git'Fellow e8b2f5cdb1
Don't check display name on null
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
2023-12-03 10:15:11 +01:00
Josh Richards f1f2bf9292
Add links to add-ons often associated with Photos
Fixes #1483

Signed-off-by: Josh Richards <josh.t.richards@gmail.com>
2023-06-20 17:05:44 -04:00
70 changed files with 116 additions and 60 deletions

View File

@ -16,7 +16,11 @@
In your Nextcloud, simply enable the Photos app through the Apps management.
The Nextcloud Photos app is only included in nextcloud v18 and higher.
Consider installing the [preview generator](https://github.com/rullzer/previewgenerator) for pre-generating thumbnails.
Optional add-ons that make the Photos app even better:
* Install [Recognize for Nextcloud](https://github.com/nextcloud/recognize) for AI-powered automatic face and object recognition. Includes automated tagging/categorizing.
* Install the [preview generator](https://github.com/rullzer/previewgenerator) if pre-generating thumbnails is desired.
* Install [Imaginary](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#previews) to speed up preview generation.
## Mobile Photos

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -57,7 +57,7 @@ OC.L10N.register(
"Open the \"{name}\" sub-directory" : "Abrir o subdirectorio «{name}»",
"Back to {folder}" : "Volver a {folder}",
"Share this folder" : "Compartir este cartafol",
"_{years} year ago_::_{years} years ago_" : ["hai {years} ano","hai {years} anos"],
"_{years} year ago_::_{years} years ago_" : ["Hai {years} ano","Hai {years} anos"],
"Enable squared photos view" : "Activar a vista de fotos cadradas",
"Default Photos upload and Albums location" : "Localización predeterminada para enviar fotos e álbums",
"Choose default Photos upload and Albums location" : "Escolla o envío predeterminado en Fotos e a localización en Álbums",

View File

@ -55,7 +55,7 @@
"Open the \"{name}\" sub-directory" : "Abrir o subdirectorio «{name}»",
"Back to {folder}" : "Volver a {folder}",
"Share this folder" : "Compartir este cartafol",
"_{years} year ago_::_{years} years ago_" : ["hai {years} ano","hai {years} anos"],
"_{years} year ago_::_{years} years ago_" : ["Hai {years} ano","Hai {years} anos"],
"Enable squared photos view" : "Activar a vista de fotos cadradas",
"Default Photos upload and Albums location" : "Localización predeterminada para enviar fotos e álbums",
"Choose default Photos upload and Albums location" : "Escolla o envío predeterminado en Fotos e a localización en Álbums",

View File

@ -99,6 +99,7 @@ OC.L10N.register(
"This folder does not exist" : "Цей каталог не існує",
"Loading folders …" : "Завантаження папок…",
"No photos in here" : "Тут немає світлин",
"Taken on {date} at {time}" : "Зроблено {date} о {time}",
"This place does not have any photos or videos yet!" : "У цього місця ще немає жодної фотографії чи відео!",
"Add photos to this place" : "Додайте фотографії до цього місця",
"Cover photo for place {placeName}" : "Обкладинка для місця {placeName}",

View File

@ -97,6 +97,7 @@
"This folder does not exist" : "Цей каталог не існує",
"Loading folders …" : "Завантаження папок…",
"No photos in here" : "Тут немає світлин",
"Taken on {date} at {time}" : "Зроблено {date} о {time}",
"This place does not have any photos or videos yet!" : "У цього місця ще немає жодної фотографії чи відео!",
"Add photos to this place" : "Додайте фотографії до цього місця",
"Cover photo for place {placeName}" : "Обкладинка для місця {placeName}",

View File

@ -353,10 +353,10 @@ class AlbumMapper {
switch ($row['collaborator_type']) {
case self::TYPE_USER:
$displayName = $this->userManager->get($row['collaborator_id'])->getDisplayName();
$displayName = $this->userManager->get($row['collaborator_id'])?->getDisplayName();
break;
case self::TYPE_GROUP:
$displayName = $this->groupManager->get($row['collaborator_id'])->getDisplayName();
$displayName = $this->groupManager->get($row['collaborator_id'])?->getDisplayName();
break;
case self::TYPE_LINK:
$displayName = $this->l->t('Public link');

View File

@ -62,7 +62,7 @@ class PlaceMapper {
$metadataQuery->joinIndex(self::METADATA_KEY);
$rows = $qb->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->in('file.mimetype', $qb->createNamedParameter($mimetypes, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere('meta_value_string IS NOT NULL')
->andWhere($qb->expr()->isNotNull('meta_value_string'))
->executeQuery()
->fetchAll();
@ -87,7 +87,7 @@ class PlaceMapper {
$rows = $qb->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->in('file.mimetype', $qb->createNamedParameter($mimetypes, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->eq('meta_value_string', $qb->createNamedParameter($place)))
->andWhere('meta_value_string IS NOT NULL')
->andWhere($qb->expr()->isNotNull('meta_value_string'))
->executeQuery()
->fetchAll();
@ -116,7 +116,7 @@ class PlaceMapper {
$rows = $qb->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->in('file.mimetype', $qb->createNamedParameter($mimetypes, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->eq('meta_value_string', $qb->createNamedParameter($place)))
->andWhere('meta_value_string IS NOT NULL')
->andWhere($qb->expr()->isNotNull('meta_value_string'))
->executeQuery()
->fetchAll();
@ -153,7 +153,7 @@ class PlaceMapper {
->andWhere($qb->expr()->eq('file.name', $qb->createNamedParameter($fileName)))
->andWhere($qb->expr()->in('file.mimetype', $qb->createNamedParameter($mimetypes, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->eq('meta_value_string', $qb->createNamedParameter($place)))
->andWhere('meta_value_string IS NOT NULL')
->andWhere($qb->expr()->isNotNull('meta_value_string'))
->executeQuery()
->fetchAll();

View File

@ -48,7 +48,7 @@ class ExifMetadataProvider implements IEventListener {
$node = $event->getNode();
if (!$node instanceof File) {
if (!$node instanceof File || $node->getSize() === 0) {
return;
}

View File

@ -45,7 +45,7 @@ class SizeMetadataProvider implements IEventListener {
$node = $event->getNode();
if (!$node instanceof File) {
if (!$node instanceof File || $node->getSize() === 0) {
return;
}

124
package-lock.json generated
View File

@ -2322,13 +2322,15 @@
},
"node_modules/@hapi/hoek": {
"version": "9.3.0",
"dev": true,
"license": "BSD-3-Clause"
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
"integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
"dev": true
},
"node_modules/@hapi/topo": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
"integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^9.0.0"
}
@ -3131,20 +3133,34 @@
}
},
"node_modules/@nextcloud/axios": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@nextcloud/axios/-/axios-2.1.0.tgz",
"integrity": "sha512-fUwRQeYfdX0sP+DJnQiqlJfB7ngNHWu6Gbi0nYapkB7IFiLECeL2SWzDOFj+M04j4ApsblEMBqGOJ38WEgdeyA==",
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@nextcloud/axios/-/axios-2.4.0.tgz",
"integrity": "sha512-ARGzT9p45L0sjRIV3JZWGPtMbwgxd4eEMcMJNn58NA7UQIsMkTwHb5pXQjL+5elXY9zp/JMz7n/7SHTp0bkuXQ==",
"dependencies": {
"@nextcloud/auth": "^2.0.0",
"@nextcloud/router": "^2.0.0",
"axios": "^0.27.2",
"tslib": "^2.4.0"
"@nextcloud/auth": "^2.1.0",
"@nextcloud/router": "^2.1.2",
"axios": "^1.4.0"
},
"engines": {
"node": "^16.0.0",
"npm": "^7.0.0 || ^8.0.0"
"node": "^20.0.0",
"npm": "^9.0.0"
}
},
"node_modules/@nextcloud/axios/node_modules/axios": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/@nextcloud/axios/node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/@nextcloud/babel-config": {
"version": "1.0.0",
"dev": true,
@ -4583,21 +4599,24 @@
},
"node_modules/@sideway/address": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
"integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@sideway/formula": {
"version": "3.0.1",
"dev": true,
"license": "BSD-3-Clause"
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
"dev": true
},
"node_modules/@sideway/pinpoint": {
"version": "2.0.0",
"dev": true,
"license": "BSD-3-Clause"
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
"dev": true
},
"node_modules/@sinclair/typebox": {
"version": "0.25.21",
@ -7046,23 +7065,28 @@
}
},
"node_modules/browserify-sign": {
"version": "4.2.1",
"license": "ISC",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz",
"integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==",
"dependencies": {
"bn.js": "^5.1.1",
"browserify-rsa": "^4.0.1",
"bn.js": "^5.2.1",
"browserify-rsa": "^4.1.0",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"elliptic": "^6.5.3",
"elliptic": "^6.5.4",
"inherits": "^2.0.4",
"parse-asn1": "^5.1.5",
"readable-stream": "^3.6.0",
"safe-buffer": "^5.2.0"
"parse-asn1": "^5.1.6",
"readable-stream": "^3.6.2",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 4"
}
},
"node_modules/browserify-sign/node_modules/readable-stream": {
"version": "3.6.0",
"license": "MIT",
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@ -14241,9 +14265,10 @@
}
},
"node_modules/joi": {
"version": "17.9.2",
"version": "17.11.0",
"resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz",
"integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^9.0.0",
"@hapi/topo": "^5.0.0",
@ -19600,7 +19625,8 @@
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"dev": true
},
"node_modules/tsutils": {
"version": "3.21.0",
@ -20313,9 +20339,10 @@
"peer": true
},
"node_modules/vue-loader": {
"version": "15.10.1",
"version": "15.11.1",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.11.1.tgz",
"integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/component-compiler-utils": "^3.1.0",
@ -20332,6 +20359,9 @@
"cache-loader": {
"optional": true
},
"prettier": {
"optional": true
},
"vue-template-compiler": {
"optional": true
}
@ -20501,15 +20531,16 @@
}
},
"node_modules/wait-on": {
"version": "7.0.1",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz",
"integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"axios": "^0.27.2",
"joi": "^17.7.0",
"axios": "^1.6.1",
"joi": "^17.11.0",
"lodash": "^4.17.21",
"minimist": "^1.2.7",
"rxjs": "^7.8.0"
"minimist": "^1.2.8",
"rxjs": "^7.8.1"
},
"bin": {
"wait-on": "bin/wait-on"
@ -20518,6 +20549,23 @@
"node": ">=12.0.0"
}
},
"node_modules/wait-on/node_modules/axios": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/wait-on/node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
"node_modules/walker": {
"version": "1.0.8",
"dev": true,

View File

@ -22,7 +22,7 @@
<template>
<NcContent app-name="photos">
<NcAppNavigation>
<NcAppNavigation :aria-label="t('photos', 'Photos')">
<template #list>
<NcAppNavigationItem :to="{name: 'all_media'}"
:name="t('photos', 'All media')"

View File

@ -73,10 +73,9 @@
<NcCheckboxRadioSwitch v-if="allowSelection"
class="selection-checkbox"
:aria-label="t('photos', 'Select image {imageName}', {imageName: file.basename})"
:checked="selected"
@update:checked="onToggle">
<span class="input-label">{{ t('photos', 'Select image {imageName}', {imageName: file.basename}) }}</span>
</NcCheckboxRadioSwitch>
@update:checked="onToggle" />
<Star v-if="file.favorite === 1"
v-once
@ -335,14 +334,14 @@ export default {
width: fit-content;
// Make the checkbox background round on hover.
:deep .checkbox-radio-switch__label {
:deep .checkbox-radio-switch__content {
padding: 10px;
box-sizing: border-box;
background: var(--color-primary-element-light);
// Add a background to the checkbox so we do not see the image through it.
&::after {
content: '';
background: var(--color-primary-element-light);
width: 16px;
height: 16px;
position: absolute;

View File

@ -47,7 +47,7 @@
<div v-else-if="!noFaces" class="faces__list">
<router-link v-for="face in orderedFaces"
:key="face.basename"
:to="`/faces/${face.basename}`">
:to="`/faces/${encodeURIComponent(face.basename)}`">
<FaceCover :base-name="face.basename" />
</router-link>
<router-link key="unassigned"

View File

@ -126,16 +126,13 @@
<NcModal v-if="showAlbumCreationForm"
key="albumCreationForm"
:close-button-contained="false"
:name="t('photos', 'New album')"
@close="showAlbumCreationForm = false">
<h2 class="timeline__heading">{{ t('photos', 'New album') }}</h2>
<AlbumForm @done="showAlbumCreationForm = false" />
</NcModal>
<NcModal v-if="showAlbumPicker"
key="albumPicker"
:close-button-contained="false"
:name="t('photos', 'Add to album')"
@close="showAlbumPicker = false">
<AlbumPicker @album-picked="addSelectionToAlbum" />
</NcModal>
@ -306,6 +303,12 @@ export default {
}
}
&__heading {
padding: calc(var(--default-grid-baseline) * 4);
margin-bottom: 0px;
padding-bottom: 0px;
}
&__file-list {
padding: 0 64px;