Skip to content

Commit

Permalink
Merge pull request #1078 from pulsejet/pulsejet/upload
Browse files Browse the repository at this point in the history
Upload functionality
  • Loading branch information
pulsejet committed Mar 20, 2024
2 parents 1637d97 + f2a335e commit 9fa4c39
Show file tree
Hide file tree
Showing 13 changed files with 693 additions and 156 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- The list of files that could not be indexed can be found in the admin panel
- To retry indexing, you can run `occ memories:index --retry`
- **Feature**: Allow changing cover photos of albums, tags, places and people ([#1071](https://github.com/pulsejet/memories/issues/1071), [#125](https://github.com/pulsejet/memories/issues/125), [#557](https://github.com/pulsejet/memories/issues/557), [#764](https://github.com/pulsejet/memories/issues/764), [#1032](https://github.com/pulsejet/memories/issues/1032))
- **Feature**: Allow direct file upload from web interface ([#69](https://github.com/pulsejet/memories/issues/69))
- **Feature**: Hide files starting with `.` in the timeline
- **Feature**: Support for 3GP videos ([#1055](https://github.com/pulsejet/memories/issues/1055))
- **Feature**: Option to show metadata in slideshow ([#819](https://github.com/pulsejet/memories/issues/819))
Expand Down
14 changes: 10 additions & 4 deletions lib/Controller/TagsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class TagsController extends GenericApiController
*
* Set tags for a file
*/
public function set(int $id, array $add, array $remove): Http\Response
public function set(int $id, ?array $add, ?array $remove): Http\Response
{
return Util::guardEx(function () use ($id, $add, $remove) {
// Check tags enabled for this user
Expand All @@ -58,9 +58,15 @@ public function set(int $id, array $add, array $remove): Http\Response
// Get mapper from tags to objects
$om = \OC::$server->get(\OCP\SystemTag\ISystemTagObjectMapper::class);

// Add and remove tags
$om->assignTags((string) $id, 'files', $add);
$om->unassignTags((string) $id, 'files', $remove);
// Add tags
if (null !== $add && \count($add) > 0) {
$om->assignTags((string) $id, 'files', $add);
}

// Remove tags
if (null !== $remove && \count($remove) > 0) {
$om->unassignTags((string) $id, 'files', $remove);
}

return new JSONResponse([], Http::STATUS_OK);
});
Expand Down
318 changes: 195 additions & 123 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@nextcloud/paths": "^2.1.0",
"@nextcloud/router": "^2.2.0",
"@nextcloud/sharing": "^0.1.0",
"@nextcloud/upload": "^1.0.5",
"@nextcloud/vue": "^8.11.0",
"filerobot-image-editor": "^4.7.0",
"fuse.js": "^7.0.0",
Expand Down
3 changes: 3 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<MoveToFolderModal />
<FaceMoveModal />
<AlbumShareModal />
<UploadModal />
</NcContent>
</template>

Expand Down Expand Up @@ -94,6 +95,7 @@ import ShareModal from '@components/modal/ShareModal.vue';
import MoveToFolderModal from '@components/modal/MoveToFolderModal.vue';
import FaceMoveModal from '@components/modal/FaceMoveModal.vue';
import AlbumShareModal from '@components/modal/AlbumShareModal.vue';
import UploadModal from '@components/modal/UploadModal.vue';
import * as utils from '@services/utils';
import * as nativex from '@native';
Expand Down Expand Up @@ -143,6 +145,7 @@ export default defineComponent({
MoveToFolderModal,
FaceMoveModal,
AlbumShareModal,
UploadModal,
ImageMultiple,
FolderIcon,
Expand Down
25 changes: 21 additions & 4 deletions src/components/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
@update:open="onClose"
>
<NcAppSettingsSection id="general-settings" :name="names.general">
<label for="timeline-path">{{ t('memories', 'Timeline Path') }}</label>
<input id="timeline-path" @click="chooseTimelinePath" v-model="config.timeline_path" type="text" readonly />
<NcTextField
:label="t('memories', 'Timeline Path')"
:label-visible="true"
v-model="config.timeline_path"
@click="chooseTimelinePath"
readonly
/>

<NcCheckboxRadioSwitch :checked.sync="config.square_thumbs" @update:checked="updateSquareThumbs" type="switch">
{{ t('memories', 'Square grid mode') }}
Expand Down Expand Up @@ -112,8 +117,13 @@
</NcAppSettingsSection>

<NcAppSettingsSection id="folders-settings" :name="names.folders">
<label for="folders-path">{{ t('memories', 'Folders Path') }}</label>
<input id="folders-path" @click="chooseFoldersPath" v-model="config.folders_path" type="text" />
<NcTextField
:label="t('memories', 'Folders Path')"
:label-visible="true"
v-model="config.folders_path"
@click="chooseFoldersPath"
readonly
/>

<NcCheckboxRadioSwitch
:checked.sync="config.show_hidden_folders"
Expand Down Expand Up @@ -170,6 +180,7 @@ import * as utils from '@services/utils';
import * as nativex from '@native';
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js';
const NcTextField = () => import('@nextcloud/vue/dist/Components/NcTextField.js');
const NcAppSettingsDialog = () => import('@nextcloud/vue/dist/Components/NcAppSettingsDialog.js');
const NcAppSettingsSection = () => import('@nextcloud/vue/dist/Components/NcAppSettingsSection.js');
const NcCheckboxRadioSwitch = () => import('@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js');
Expand All @@ -183,6 +194,7 @@ export default defineComponent({
components: {
NcButton,
NcTextField,
NcAppSettingsDialog,
NcAppSettingsSection,
NcCheckboxRadioSwitch,
Expand Down Expand Up @@ -372,6 +384,11 @@ export default defineComponent({
position: relative;
}
input[readonly] {
cursor: pointer;
user-select: none;
}
.app-settings-section {
margin-bottom: 20px !important;
}
Expand Down
33 changes: 22 additions & 11 deletions src/components/modal/AlbumPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ export default defineComponent({
type: Boolean,
default: false,
},
/** Initial album selection */
initialSelection: {
type: Array as PropType<IAlbum[]>,
required: false,
},
},
emits: {
Expand Down Expand Up @@ -185,19 +191,24 @@ export default defineComponent({
// create search provider
this.fuse = new Fuse(this.albums, { keys: ['name'] });
// reset selection
this.initSelection = new Set();
this.selection = new Set();
this.deselection = new Set();
// if only one photo is selected, get the albums of that photo
const fileid = this.photos.length === 1 ? this.photos[0].fileid : 0;
if (fileid) {
const selIds = new Set((await dav.getAlbums(fileid)).map((a) => a.album_id));
this.initSelection = new Set(this.albums.filter((a) => selIds.has(a.album_id)));
this.selection = new Set(this.initSelection);
// get initial selection
let initSelIds: number[] = [];
const singleFileId = this.photos.length === 1 ? this.photos[0].fileid : 0;
if (this.initialSelection) {
// check if selection was passed as a prop
initSelIds = this.initialSelection.map((a) => a.album_id);
} else if (singleFileId) {
// if only one photo is selected, get the albums of that photo
const pAlbums = await dav.getAlbums(singleFileId);
initSelIds = pAlbums.map((a) => a.album_id);
}
// initialize all sets
this.initSelection = new Set(this.albums.filter((a) => initSelIds.includes(a.album_id)));
this.selection = new Set(this.initSelection);
this.deselection = new Set();
// restore selection
if (preserveSelection) {
this.albums.filter((a) => prevSel.has(a.album_id)).forEach(this.selection.add, this.selection);
Expand Down
5 changes: 5 additions & 0 deletions src/components/modal/Modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
:outTransition="true"
:style="{ width: isSidebarShown ? `calc(100% - ${sidebarWidth}px)` : null }"
:additionalTrapElements="trapElements"
:canClose="canClose"
@close="cleanup"
>
<div class="container" @keydown.stop="0">
Expand Down Expand Up @@ -45,6 +46,10 @@ export default defineComponent({
type: String as PropType<string | null>,
default: null,
},
canClose: {
type: Boolean,
default: true,
},
},
data: () => ({
Expand Down
26 changes: 26 additions & 0 deletions src/components/modal/UploadMenuItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template>
<NcButton :aria-label="t('memories', 'Favorite')" type="primary" @click="upload">
<template #icon> <UploadIcon :size="20" /> </template>
</NcButton>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js';
import UploadIcon from 'vue-material-design-icons/Upload.vue';
export default defineComponent({
name: 'UploadMenuItem',
components: {
NcButton,
UploadIcon,
},
methods: {
upload() {
_m.modals.upload();
},
},
});
</script>
Loading

0 comments on commit 9fa4c39

Please sign in to comment.