@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@christianriedl/media",
3
- "version": "1.0.204",
3
+ "version": "1.0.206",
4
4
  "description": "RIC media interfaces",
5
5
 
6
6
  "main": "dist/index.js",
@@ -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 folderId = decodeURIComponent(route.query!.id!.toString());
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
- folder.value = mediaService.getFolder(folderId);
43
- if (!folder.value) {
44
- const split = folderId.split(/[.|]/);
45
- await mediaService.getPhotosByCriteria(split[1], split[2]);
46
- folder.value = mediaService.getFolder(folderId);
47
- if (!folder.value)
48
- return;
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
- router.push({ path: 'photoalbum', query: { id: folder.value!.dlnaid, start: item.dlnaid } });
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
- let url = `https://www.christian-riedl.com/media/apiimage/Thumbnail?image=${folder.value!.url}${image.url}&tresX=${image.thumbWidth}&tresY=${image.thumbHeight}`;
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>