@christianriedl/media 1.0.204 → 1.0.206
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -457,7 +457,7 @@
|
|
|
457
457
|
</v-carousel-item>
|
|
458
458
|
</v-carousel>
|
|
459
459
|
<v-dialog v-model="infoDialog" :fullscreen="isMobile" >
|
|
460
|
-
<v-card v-if="infoDialog" width="600" >
|
|
460
|
+
<v-card v-if="infoDialog" :width="isMobile ? 400 : 600" >
|
|
461
461
|
<v-card-title class="headline">Metadata</v-card-title>
|
|
462
462
|
<v-card-text>
|
|
463
463
|
<v-container>
|
|
@@ -171,6 +171,9 @@
|
|
|
171
171
|
selected.rating = Number(value);
|
|
172
172
|
initialize(selectedFolder.value.name);
|
|
173
173
|
}
|
|
174
|
+
function onSearch() {
|
|
175
|
+
router.push({ path: 'photothumbnails' });
|
|
176
|
+
}
|
|
174
177
|
async function initialize(selectedName?: string) {
|
|
175
178
|
let root = await mediaService.getPhotosByCriteria(stars(), selected.criteria);
|
|
176
179
|
if (selected.criteria != 'ye' && selectedName) {
|
|
@@ -223,6 +226,10 @@
|
|
|
223
226
|
<v-select v-model="root" :items="roots" density="compact" persistent-hint
|
|
224
227
|
@update:modelValue="onRootChange" hide-details single-line>
|
|
225
228
|
</v-select>
|
|
229
|
+
<v-btn v-if="!backVisible" @click="onSearch">
|
|
230
|
+
{{ isMobile ? "" : "SEARCH" }}
|
|
231
|
+
<v-icon icon="$search" />
|
|
232
|
+
</v-btn>
|
|
226
233
|
<v-btn v-if="!isMobile" @click="uploadVisible = !uploadVisible">
|
|
227
234
|
UPLOAD
|
|
228
235
|
<v-icon icon="$upload" />
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
const isMobile = appState.isMobile && appState.device !== EDevice.iPad;
|
|
18
18
|
const router = useRouter();
|
|
19
19
|
const route = useRoute();
|
|
20
|
-
const
|
|
20
|
+
const title = ref("");
|
|
21
|
+
const withPerson = ref(false);
|
|
22
|
+
const withLocation = ref(false);
|
|
21
23
|
const photos = ref<IPictureFile[]>([]);
|
|
22
24
|
const minImageWidth = 100;
|
|
23
25
|
const numImagesPerRow = Math.min(window.innerWidth / minImageWidth, 12);
|
|
@@ -39,23 +41,106 @@
|
|
|
39
41
|
if (!mediaService.medialists["Picture.Event"])
|
|
40
42
|
await (mediaService as MediaService).getLists(EMediaType.Picture);
|
|
41
43
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
if (route.query) {
|
|
45
|
+
if (route.query.id) {
|
|
46
|
+
const folderId = decodeURIComponent(route.query.id.toString());
|
|
47
|
+
folder.value = mediaService.getFolder(folderId);
|
|
48
|
+
if (!folder.value) {
|
|
49
|
+
const split = folderId.split(/[.|]/);
|
|
50
|
+
await mediaService.getPhotosByCriteria(split[1], split[2]);
|
|
51
|
+
folder.value = mediaService.getFolder(folderId);
|
|
52
|
+
if (!folder.value)
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
folder.value = await mediaService.getPhotos(folder.value);
|
|
56
|
+
photos.value.splice(0, photos.value.length, ...folder.value!.files as IPictureFile[]);
|
|
57
|
+
}
|
|
58
|
+
else if (route.query.title) {
|
|
59
|
+
title.value = route.query.title.toString();
|
|
60
|
+
if (route.query.pers !== undefined)
|
|
61
|
+
withPerson.value = true;
|
|
62
|
+
if (route.query.loc !== undefined)
|
|
63
|
+
withLocation.value = true;
|
|
64
|
+
onSearch();
|
|
65
|
+
}
|
|
49
66
|
}
|
|
50
|
-
folder.value = await mediaService.getPhotos(folder.value);
|
|
51
|
-
photos.value.splice(0, photos.value.length, ...folder.value!.files as IPictureFile[]);
|
|
52
67
|
console.log(photos.value.length);
|
|
53
68
|
})
|
|
69
|
+
function inMediaList (listName: string, regex: RegExp) : number[] | undefined
|
|
70
|
+
{
|
|
71
|
+
const list = mediaService.medialists[listName];
|
|
72
|
+
let idxs: number[] | undefined;
|
|
73
|
+
for (let i = 0; i < list.values.length; i++) {
|
|
74
|
+
if (regex.test (list.values[i].toLowerCase())) {
|
|
75
|
+
if (!idxs)
|
|
76
|
+
idxs = [];
|
|
77
|
+
idxs.push(i);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return idxs;
|
|
81
|
+
}
|
|
82
|
+
async function searchPictures(titlePattern: string, searchPerson: boolean, searchLocation: boolean): Promise<IPictureFile[]> {
|
|
83
|
+
const regex = new RegExp(`^.*${titlePattern.toLowerCase()}.*$`);
|
|
84
|
+
const root = mediaService.getFolder("ph.all.ye|");
|
|
85
|
+
const result: IPictureFile[] = [];
|
|
86
|
+
const personIdxs = searchPerson ? inMediaList ("Picture.Person", regex) : undefined;
|
|
87
|
+
const locationIdxs = searchLocation ? inMediaList ("Picture.Location", regex) : undefined;
|
|
88
|
+
|
|
89
|
+
photos.value.splice(0, photos.value.length);
|
|
90
|
+
for (let i = 0; i < root.folders.length; i++) {
|
|
91
|
+
const yf = root.folders[i];
|
|
92
|
+
mediaService.prepare (yf);
|
|
93
|
+
for (let j = 0; j < yf.folders.length; j++) {
|
|
94
|
+
const af = yf.folders[j];
|
|
95
|
+
mediaService.prepare (af);
|
|
96
|
+
const album = await mediaService.getPhotos(af);
|
|
97
|
+
if (album) {
|
|
98
|
+
for (let k = 0; k < album.files.length; k++) {
|
|
99
|
+
let match = false;
|
|
100
|
+
const photo = album.files[k] as IPictureFile;
|
|
101
|
+
if (personIdxs && photo.personIdxs) {
|
|
102
|
+
for (let l = 0; l < photo.personIdxs.length; l++) {
|
|
103
|
+
if (personIdxs.includes (photo.personIdxs[l])) {
|
|
104
|
+
match = true; break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (locationIdxs && photo.locationIdx) {
|
|
109
|
+
if (locationIdxs.includes (photo.locationIdx))
|
|
110
|
+
match = true;
|
|
111
|
+
}
|
|
112
|
+
if (regex.test (photo.name.toLowerCase()))
|
|
113
|
+
match = true;
|
|
114
|
+
|
|
115
|
+
if (match)
|
|
116
|
+
result.push(photo);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
async function onSearch() {
|
|
124
|
+
const list = await searchPictures (title.value, withPerson.value, withLocation.value);
|
|
125
|
+
photos.value.splice(0, photos.value.length, ...list);
|
|
126
|
+
console.log(photos.value.length);
|
|
127
|
+
}
|
|
54
128
|
function onClick(item: IPictureFile) {
|
|
55
129
|
if (selectMode.value)
|
|
56
130
|
item.selected = !item.selected;
|
|
57
|
-
else
|
|
58
|
-
|
|
131
|
+
else {
|
|
132
|
+
if(folder.value)
|
|
133
|
+
router.push({ path: 'photoalbum', query: { id: folder.value!.dlnaid, start: item.dlnaid } });
|
|
134
|
+
else {
|
|
135
|
+
let url = `${route.path}?title=${title.value}`;
|
|
136
|
+
if (withPerson.value)
|
|
137
|
+
url += '&pers';
|
|
138
|
+
if (withLocation.value)
|
|
139
|
+
url += '&loc';
|
|
140
|
+
router.options.history.replace (url);
|
|
141
|
+
router.push({ path: 'photoalbum', query: { id: item.dlnaParentId, start: item.dlnaid } });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
59
144
|
}
|
|
60
145
|
async function onShare() {
|
|
61
146
|
const picIds: string[] = [];
|
|
@@ -91,7 +176,8 @@
|
|
|
91
176
|
showDownload.value = false;
|
|
92
177
|
}
|
|
93
178
|
function getThumbnailUrl(image: IPictureFile) : string {
|
|
94
|
-
|
|
179
|
+
const f = folder.value ? folder.value : mediaService.getFolder (image.dlnaParentId);
|
|
180
|
+
let url = `https://www.christian-riedl.com/media/apiimage/Thumbnail?image=${f.url}${image.url}&tresX=${image.thumbWidth}&tresY=${image.thumbHeight}`;
|
|
95
181
|
if (image.orientation && (image.orientation === EOrientation.BottomLeft || image.orientation === EOrientation.TopRight))
|
|
96
182
|
url += '&orientation=' + Number(image.orientation);
|
|
97
183
|
return encodeURI(url);
|
|
@@ -117,6 +203,21 @@
|
|
|
117
203
|
<v-btn icon="$download" variant="tonal" @click="onDownload"></v-btn>
|
|
118
204
|
</v-col>
|
|
119
205
|
</v-row>
|
|
206
|
+
<v-row v-else dense align="center">
|
|
207
|
+
<v-col cols="6">
|
|
208
|
+
<v-text-field label="Titel" v-model="title" hide-details clearable ></v-text-field>
|
|
209
|
+
</v-col>
|
|
210
|
+
<v-col cols="2">
|
|
211
|
+
<v-checkbox v-model="withLocation" hide-details density="compact" label="Loc"></v-checkbox>
|
|
212
|
+
</v-col>
|
|
213
|
+
<v-col cols="2">
|
|
214
|
+
<v-checkbox v-model="withPerson" hide-details density="compact" label="Pers"></v-checkbox>
|
|
215
|
+
</v-col>
|
|
216
|
+
<v-col cols="2">
|
|
217
|
+
<v-btn v-if="isMobile" icon="$search" variant="tonal" @click="onSearch"></v-btn>
|
|
218
|
+
<v-btn v-else prepend-icon="$search" variant="tonal" @click="onSearch">Search</v-btn>
|
|
219
|
+
</v-col>
|
|
220
|
+
</v-row>
|
|
120
221
|
<v-row v-if="mediaAppConfig.showThumbnailText" dense align="center" >
|
|
121
222
|
<v-col :cols="numColsPerImage" class="bg-grey-darken-2 thumbnail" v-for="(image, index) in photos" :key="index">
|
|
122
223
|
<div v-if="image.title" class="text-caption text-no-wrap">{{image.title!.substring(0, textTrim)}}</div>
|