@christianriedl/media 1.0.205 → 1.0.207

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.205",
3
+ "version": "1.0.207",
4
4
  "description": "RIC media interfaces",
5
5
 
6
6
  "main": "dist/index.js",
@@ -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,115 @@
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, rating: number, maxPictures: number = 200): 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
+ let count = 0;
89
+
90
+ photos.value.splice(0, photos.value.length);
91
+ for (let i = 0; i < root.folders.length; i++) {
92
+ const yf = root.folders[i];
93
+ mediaService.prepare (yf);
94
+ for (let j = 0; j < yf.folders.length; j++) {
95
+ const af = yf.folders[j];
96
+ mediaService.prepare (af);
97
+ const album = await mediaService.getPhotos(af);
98
+ if (album) {
99
+ for (let k = 0; k < album.files.length; k++) {
100
+ let match = false;
101
+ const photo = album.files[k] as IPictureFile;
102
+ if (photo.rating < rating)
103
+ continue;
104
+ if (personIdxs && photo.personIdxs) {
105
+ for (let l = 0; l < photo.personIdxs.length; l++) {
106
+ if (personIdxs.includes (photo.personIdxs[l])) {
107
+ match = true; break;
108
+ }
109
+ }
110
+ }
111
+ if (locationIdxs && photo.locationIdx) {
112
+ if (locationIdxs.includes (photo.locationIdx))
113
+ match = true;
114
+ }
115
+ if (regex.test (photo.name.toLowerCase()))
116
+ match = true;
117
+
118
+ if (match) {
119
+ count++;
120
+ if (result.length < maxPictures)
121
+ result.push(photo);
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+ if (result.length >= maxPictures) {
128
+ alert (`Too many pictures (${count}) found, limit : ${result.length}`)
129
+ }
130
+ return result;
131
+ }
132
+ async function onSearch() {
133
+ const list = await searchPictures (title.value, withPerson.value, withLocation.value, mediaService.photoSelection.rating, isMobile ? 200 : 500);
134
+ photos.value.splice(0, photos.value.length, ...list);
135
+ console.log(photos.value.length);
136
+ }
54
137
  function onClick(item: IPictureFile) {
55
138
  if (selectMode.value)
56
139
  item.selected = !item.selected;
57
- else
58
- router.push({ path: 'photoalbum', query: { id: folder.value!.dlnaid, start: item.dlnaid } });
140
+ else {
141
+ if(folder.value)
142
+ router.push({ path: 'photoalbum', query: { id: folder.value!.dlnaid, start: item.dlnaid } });
143
+ else {
144
+ let url = `${route.path}?title=${title.value}`;
145
+ if (withPerson.value)
146
+ url += '&pers';
147
+ if (withLocation.value)
148
+ url += '&loc';
149
+ router.options.history.replace (url);
150
+ router.push({ path: 'photoalbum', query: { id: item.dlnaParentId, start: item.dlnaid } });
151
+ }
152
+ }
59
153
  }
60
154
  async function onShare() {
61
155
  const picIds: string[] = [];
@@ -91,7 +185,8 @@
91
185
  showDownload.value = false;
92
186
  }
93
187
  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}`;
188
+ const f = folder.value ? folder.value : mediaService.getFolder (image.dlnaParentId);
189
+ let url = `https://www.christian-riedl.com/media/apiimage/Thumbnail?image=${f.url}${image.url}&tresX=${image.thumbWidth}&tresY=${image.thumbHeight}`;
95
190
  if (image.orientation && (image.orientation === EOrientation.BottomLeft || image.orientation === EOrientation.TopRight))
96
191
  url += '&orientation=' + Number(image.orientation);
97
192
  return encodeURI(url);
@@ -117,6 +212,21 @@
117
212
  <v-btn icon="$download" variant="tonal" @click="onDownload"></v-btn>
118
213
  </v-col>
119
214
  </v-row>
215
+ <v-row v-else dense align="center">
216
+ <v-col cols="6">
217
+ <v-text-field label="Titel" v-model="title" hide-details clearable ></v-text-field>
218
+ </v-col>
219
+ <v-col cols="2">
220
+ <v-checkbox v-model="withLocation" hide-details density="compact" label="Loc"></v-checkbox>
221
+ </v-col>
222
+ <v-col cols="2">
223
+ <v-checkbox v-model="withPerson" hide-details density="compact" label="Pers"></v-checkbox>
224
+ </v-col>
225
+ <v-col cols="2">
226
+ <v-btn v-if="isMobile" icon="$search" variant="tonal" @click="onSearch"></v-btn>
227
+ <v-btn v-else prepend-icon="$search" variant="tonal" @click="onSearch">Search</v-btn>
228
+ </v-col>
229
+ </v-row>
120
230
  <v-row v-if="mediaAppConfig.showThumbnailText" dense align="center" >
121
231
  <v-col :cols="numColsPerImage" class="bg-grey-darken-2 thumbnail" v-for="(image, index) in photos" :key="index">
122
232
  <div v-if="image.title" class="text-caption text-no-wrap">{{image.title!.substring(0, textTrim)}}</div>