@things-factory/gallery 10.1.246 → 10.1.248

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.
Files changed (75) hide show
  1. package/package.json +10 -10
  2. package/dist-client/bootstrap.d.ts +0 -2
  3. package/dist-client/bootstrap.js +0 -26
  4. package/dist-client/bootstrap.js.map +0 -1
  5. package/dist-client/components/gallery-forms.d.ts +0 -31
  6. package/dist-client/components/gallery-forms.js +0 -223
  7. package/dist-client/components/gallery-forms.js.map +0 -1
  8. package/dist-client/components/gallery-saver-setting-let.d.ts +0 -11
  9. package/dist-client/components/gallery-saver-setting-let.js +0 -81
  10. package/dist-client/components/gallery-saver-setting-let.js.map +0 -1
  11. package/dist-client/components/gallery-show.d.ts +0 -46
  12. package/dist-client/components/gallery-show.js +0 -316
  13. package/dist-client/components/gallery-show.js.map +0 -1
  14. package/dist-client/components/gallery-uploader.d.ts +0 -57
  15. package/dist-client/components/gallery-uploader.js +0 -624
  16. package/dist-client/components/gallery-uploader.js.map +0 -1
  17. package/dist-client/components/gallery-viewer.d.ts +0 -30
  18. package/dist-client/components/gallery-viewer.js +0 -429
  19. package/dist-client/components/gallery-viewer.js.map +0 -1
  20. package/dist-client/index.d.ts +0 -1
  21. package/dist-client/index.js +0 -2
  22. package/dist-client/index.js.map +0 -1
  23. package/dist-client/pages/gallery-page.d.ts +0 -54
  24. package/dist-client/pages/gallery-page.js +0 -590
  25. package/dist-client/pages/gallery-page.js.map +0 -1
  26. package/dist-client/route.d.ts +0 -1
  27. package/dist-client/route.js +0 -9
  28. package/dist-client/route.js.map +0 -1
  29. package/dist-client/tsconfig.tsbuildinfo +0 -1
  30. package/dist-client/utils/gallery-api.d.ts +0 -99
  31. package/dist-client/utils/gallery-api.js +0 -46
  32. package/dist-client/utils/gallery-api.js.map +0 -1
  33. package/dist-client/utils/gallery-badge.d.ts +0 -4
  34. package/dist-client/utils/gallery-badge.js +0 -45
  35. package/dist-client/utils/gallery-badge.js.map +0 -1
  36. package/dist-client/utils/gallery-saver.d.ts +0 -6
  37. package/dist-client/utils/gallery-saver.js +0 -69
  38. package/dist-client/utils/gallery-saver.js.map +0 -1
  39. package/dist-client/utils/gallery-words.d.ts +0 -7
  40. package/dist-client/utils/gallery-words.js +0 -20
  41. package/dist-client/utils/gallery-words.js.map +0 -1
  42. package/dist-client/utils/photo-prep.d.ts +0 -10
  43. package/dist-client/utils/photo-prep.js +0 -102
  44. package/dist-client/utils/photo-prep.js.map +0 -1
  45. package/dist-server/attachment-reader.d.ts +0 -1
  46. package/dist-server/attachment-reader.js +0 -13
  47. package/dist-server/attachment-reader.js.map +0 -1
  48. package/dist-server/index.d.ts +0 -1
  49. package/dist-server/index.js +0 -11
  50. package/dist-server/index.js.map +0 -1
  51. package/dist-server/role-tasks.d.ts +0 -2
  52. package/dist-server/role-tasks.js +0 -15
  53. package/dist-server/role-tasks.js.map +0 -1
  54. package/dist-server/service/gallery/gallery-resolver.d.ts +0 -29
  55. package/dist-server/service/gallery/gallery-resolver.js +0 -613
  56. package/dist-server/service/gallery/gallery-resolver.js.map +0 -1
  57. package/dist-server/service/gallery/gallery-rules.d.ts +0 -90
  58. package/dist-server/service/gallery/gallery-rules.js +0 -182
  59. package/dist-server/service/gallery/gallery-rules.js.map +0 -1
  60. package/dist-server/service/gallery/gallery-service.d.ts +0 -37
  61. package/dist-server/service/gallery/gallery-service.js +0 -234
  62. package/dist-server/service/gallery/gallery-service.js.map +0 -1
  63. package/dist-server/service/gallery/gallery-types.d.ts +0 -65
  64. package/dist-server/service/gallery/gallery-types.js +0 -239
  65. package/dist-server/service/gallery/gallery-types.js.map +0 -1
  66. package/dist-server/service/gallery/gallery.d.ts +0 -84
  67. package/dist-server/service/gallery/gallery.js +0 -335
  68. package/dist-server/service/gallery/gallery.js.map +0 -1
  69. package/dist-server/service/gallery/index.d.ts +0 -4
  70. package/dist-server/service/gallery/index.js +0 -8
  71. package/dist-server/service/gallery/index.js.map +0 -1
  72. package/dist-server/service/index.d.ts +0 -7
  73. package/dist-server/service/index.js +0 -23
  74. package/dist-server/service/index.js.map +0 -1
  75. package/dist-server/tsconfig.tsbuildinfo +0 -1
@@ -1,234 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isModerator = exports.GALLERY_REF_TYPE = void 0;
4
- exports.viewerOf = viewerOf;
5
- exports.visiblePost = visiblePost;
6
- exports.photosOf = photosOf;
7
- exports.eventsOf = eventsOf;
8
- exports.decorate = decorate;
9
- exports.isOpenEvent = isOpenEvent;
10
- exports.maySeeEvent = maySeeEvent;
11
- exports.eventsSeenBetween = eventsSeenBetween;
12
- exports.openEvent = openEvent;
13
- exports.tellFirstPhoto = tellFirstPhoto;
14
- exports.tellHidden = tellHidden;
15
- /*
16
- * What the gallery's doors do with the database (ADR-0165 decisions 2-7): who sees a post, its photos and event, which
17
- * events a person may post to, opening an event's gallery, and the two notices.
18
- */
19
- const typeorm_1 = require("typeorm");
20
- const attachment_base_1 = require("@things-factory/attachment-base");
21
- const auth_base_1 = require("@things-factory/auth-base");
22
- const calendar_1 = require("@things-factory/calendar");
23
- const translator_1 = require("@things-factory/i18n-base/translator");
24
- const notification_1 = require("@things-factory/notification");
25
- const shell_1 = require("@things-factory/shell");
26
- const gallery_1 = require("./gallery");
27
- const gallery_rules_1 = require("./gallery-rules");
28
- /** The photos of a post hang on it under this `refType` (attachment-base). */
29
- exports.GALLERY_REF_TYPE = 'Gallery Post';
30
- const isId = (id) => !!id && /^[0-9a-f-]{36}$/i.test(id);
31
- async function holds(context, category, privilege, key) {
32
- const state = context?.state ?? {};
33
- const { domain, user, unsafeIP, prohibitedPrivileges } = state;
34
- if (!domain || !user)
35
- return false;
36
- /* Asked once per request - a list asks it for each row. */
37
- state[key] ??= (0, auth_base_1.checkPermission)({ category, privilege, owner: true }, user, domain, unsafeIP, prohibitedPrivileges).then(Boolean);
38
- return await state[key];
39
- }
40
- /** Whether the request moderates the gallery - the module's one task, `gallery.moderation`. */
41
- const isModerator = (context) => holds(context, 'gallery', 'mutation', '__galleryModerator');
42
- exports.isModerator = isModerator;
43
- /** Whether the request reads the domain's whole calendar. */
44
- const readsCalendar = (context) => holds(context, 'calendar', 'query', '__galleryCalendarReader');
45
- /** The request's person as a post's viewer - asked once per request. */
46
- async function viewerOf(context) {
47
- const state = context.state;
48
- if (!state.__galleryViewer) {
49
- const people = await (0, auth_base_1.getDomainAssignees)(state.domain, state.tx);
50
- state.__galleryViewer = {
51
- userId: state.user.id,
52
- moderator: await (0, exports.isModerator)(context),
53
- activePeople: new Set(people.map(one => one.id))
54
- };
55
- }
56
- return state.__galleryViewer;
57
- }
58
- /** The post as the request may see it, or nothing - one answer for "none" and "not for you". */
59
- async function visiblePost(id, context, tx) {
60
- const { domain, user } = context?.state ?? {};
61
- if (!isId(id) || !domain || !user)
62
- return undefined;
63
- const post = await (0, shell_1.getRepository)(gallery_1.GalleryPost, tx).findOne({ where: { id, domain: { id: domain.id } } });
64
- if (!post)
65
- return undefined;
66
- return (0, gallery_rules_1.seesPost)(post, await viewerOf(context)) ? post : undefined;
67
- }
68
- /** The photos of each post, in the order they were added. */
69
- async function photosOf(postIds, domainId, tx) {
70
- const out = new Map();
71
- if (!postIds.length)
72
- return out;
73
- const rows = await (0, shell_1.getRepository)(attachment_base_1.Attachment, tx).find({
74
- where: { domain: { id: domainId }, refType: exports.GALLERY_REF_TYPE, refBy: (0, typeorm_1.In)(postIds) },
75
- order: { createdAt: 'ASC' }
76
- });
77
- for (const one of rows)
78
- out.set(one.refBy, [...(out.get(one.refBy) ?? []), one]);
79
- return out;
80
- }
81
- /** The name, time and place of each event. */
82
- async function eventsOf(eventIds, domainId, tx) {
83
- const ids = [...new Set(eventIds.filter(isId))];
84
- if (!ids.length)
85
- return new Map();
86
- const rows = await (0, shell_1.getRepository)(calendar_1.Event, tx).find({ where: { id: (0, typeorm_1.In)(ids), domain: { id: domainId } } });
87
- return new Map(rows.map(one => [one.id, one]));
88
- }
89
- /** Puts on each post what its fields answer from - who posted it, its photos, its event and whether the request's person likes it. */
90
- async function decorate(posts, context) {
91
- const { domain, user, tx } = context.state;
92
- const ids = posts.map(one => one.id);
93
- const photos = await photosOf(ids, domain.id, tx);
94
- const events = await eventsOf(posts.map(one => one.eventId), domain.id, tx);
95
- const liked = ids.length
96
- ? await (0, shell_1.getRepository)(gallery_1.GalleryLike, tx).find({ where: { post: { id: (0, typeorm_1.In)(ids) }, user: { id: user.id } } })
97
- : [];
98
- const likedIds = new Set(liked.map(one => one.postId));
99
- const creatorIds = [...new Set(posts.map(one => one.creatorId).filter(Boolean))];
100
- const creators = new Map((creatorIds.length ? await (0, shell_1.getRepository)(auth_base_1.User, tx).find({ where: { id: (0, typeorm_1.In)(creatorIds) } }) : []).map(one => [
101
- one.id,
102
- one
103
- ]));
104
- for (const one of posts) {
105
- one.__creator = creators.get(one.creatorId) ?? null;
106
- one.__photos = photos.get(one.id) ?? [];
107
- one.__event = one.eventId ? (events.get(one.eventId) ?? null) : null;
108
- one.__liked = likedIds.has(one.id);
109
- }
110
- return posts;
111
- }
112
- /** Whether the event's gallery is open. */
113
- async function isOpenEvent(eventId, domainId, tx) {
114
- return !!(await (0, shell_1.getRepository)(gallery_1.GalleryEvent, tx).findOne({
115
- where: { domain: { id: domainId }, event: { id: eventId } }
116
- }));
117
- }
118
- /**
119
- * Whether the request's person may post to the event: its gallery is open, or they see the event - they are named on
120
- * it or responsible for it, or they read the whole calendar. An event they cannot see takes no photo (판정 1).
121
- */
122
- async function maySeeEvent(eventId, context, tx) {
123
- const { domain, user } = context.state;
124
- if (!isId(eventId))
125
- return undefined;
126
- const event = await (0, shell_1.getRepository)(calendar_1.Event, tx).findOne({ where: { id: eventId, domain: { id: domain.id } } });
127
- if (!event)
128
- return undefined;
129
- if (event.organizerId === user.id)
130
- return event;
131
- if (await isOpenEvent(eventId, domain.id, tx))
132
- return event;
133
- if (await (0, shell_1.getRepository)(calendar_1.Attendee, tx).findOne({
134
- where: { domain: { id: domain.id }, event: { id: eventId }, user: { id: user.id } }
135
- }))
136
- return event;
137
- return (await readsCalendar(context)) ? event : undefined;
138
- }
139
- /** The events the person may post to that overlap [from, to): their own, the open ones, and all when they read the calendar. */
140
- async function eventsSeenBetween(context, from, to, tx) {
141
- const { domain, user } = context.state;
142
- const qb = (0, shell_1.getRepository)(calendar_1.Event, tx)
143
- .createQueryBuilder('E')
144
- .where('E.domain = :domain', { domain: domain.id })
145
- .andWhere('E.startAt < :to AND E.endAt > :from', { from, to });
146
- if (!(await readsCalendar(context))) {
147
- const named = await (0, shell_1.getRepository)(calendar_1.Attendee, tx).find({
148
- where: { domain: { id: domain.id }, user: { id: user.id } }
149
- });
150
- const open = await (0, shell_1.getRepository)(gallery_1.GalleryEvent, tx).find({ where: { domain: { id: domain.id } } });
151
- const ids = [...new Set([...named.map(one => one.eventId), ...open.map(one => one.eventId)].filter(Boolean))];
152
- qb.andWhere(ids.length ? '(E.organizer = :me OR E.id IN (:...ids))' : 'E.organizer = :me', { me: user.id, ids });
153
- }
154
- return await qb.orderBy('E.startAt', 'DESC').take(50).getMany();
155
- }
156
- /** Opens the event's gallery, once. */
157
- async function openEvent(eventId, context, tx) {
158
- const { domain, user } = context.state;
159
- if (await isOpenEvent(eventId, domain.id, tx))
160
- return;
161
- await (0, shell_1.getRepository)(gallery_1.GalleryEvent, tx).save({ domain, event: { id: eventId }, creator: user, updater: user });
162
- }
163
- /** The sentences in `lng` from this module's translations, the English one where `lng` has none. */
164
- const sayIn = (lng) => (key, english, params = {}) => (0, translator_1.translatorFor)(lng)(key, {
165
- ...params,
166
- defaultValue: english.replace(/\{(\w+)\}/g, (_, name) => String(params[name] ?? ''))
167
- });
168
- /** The people to tell, as notification takes them - only those who can sign in. */
169
- async function receiversOf(userIds, tx) {
170
- if (!userIds.length)
171
- return [];
172
- const people = await (0, shell_1.getRepository)(auth_base_1.User, tx).find({ where: { id: (0, typeorm_1.In)(userIds) } });
173
- return people
174
- .filter(one => one.status === auth_base_1.UserStatus.ACTIVATED)
175
- .map(one => ({ id: one.id, email: one.email, locale: one.locale }));
176
- }
177
- function tell(context, notice) {
178
- (0, notification_1.sendNoticeWhenCommitted)(context, { ...notice, link: (0, notification_1.noticeLinkOf)(context, notice.address) });
179
- }
180
- /**
181
- * When the post is the event's first, tells the people named on the event - everyone of the domain when it names
182
- * nobody - that its photos are up (decision 6). Once per event: a later post is not the first.
183
- */
184
- async function tellFirstPhoto(context, post, eventId) {
185
- const { domain, user, tx } = context.state;
186
- const others = await (0, shell_1.getRepository)(gallery_1.GalleryPost, tx)
187
- .createQueryBuilder('P')
188
- .where('P.domain = :domain AND P.event = :event AND P.id != :id', {
189
- domain: domain.id,
190
- event: eventId,
191
- id: post.id
192
- })
193
- .withDeleted()
194
- .getCount();
195
- if (others)
196
- return;
197
- const event = await (0, shell_1.getRepository)(calendar_1.Event, tx).findOne({ where: { id: eventId } });
198
- if (!event)
199
- return;
200
- const attendees = await (0, shell_1.getRepository)(calendar_1.Attendee, tx).find({
201
- where: { domain: { id: domain.id }, event: { id: eventId } }
202
- });
203
- const members = attendees.some(one => one.userId) ? [] : (await (0, auth_base_1.getDomainAssignees)(domain, tx)).map(one => one.id);
204
- const receivers = await receiversOf((0, gallery_rules_1.firstPhotoReceivers)(attendees.map(one => one.userId).filter(Boolean), members, user.id), tx);
205
- if (!receivers.length)
206
- return;
207
- tell(context, {
208
- type: 'gallery',
209
- receivers,
210
- words: lng => (0, gallery_rules_1.firstPhotoWords)(event, user.name ?? '', post.caption, sayIn(lng)),
211
- address: (0, gallery_rules_1.galleryAddressOf)({ eventId }),
212
- label: `gallery first-photo ${eventId}`,
213
- /* Photos are no news for the inbox of another app - the app and push carry it, mail only where the domain turned it on. */
214
- channels: { email: false }
215
- });
216
- }
217
- /** Tells the owner that a moderator hid their post, and why (decision 5). */
218
- async function tellHidden(context, post, reason) {
219
- if (!post.creatorId || post.creatorId === context.state.user.id)
220
- return;
221
- const receivers = await receiversOf([post.creatorId], context.state.tx);
222
- if (!receivers.length)
223
- return;
224
- tell(context, {
225
- type: 'gallery',
226
- level: 'warn',
227
- receivers,
228
- words: lng => (0, gallery_rules_1.hiddenWords)(reason, sayIn(lng)),
229
- address: (0, gallery_rules_1.galleryAddressOf)({ postId: post.id }),
230
- label: `gallery hidden ${post.id}`,
231
- channels: { email: false }
232
- });
233
- }
234
- //# sourceMappingURL=gallery-service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gallery-service.js","sourceRoot":"","sources":["../../../server/service/gallery/gallery-service.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * What the gallery's doors do with the database (ADR-0165 decisions 2-7): who sees a post, its photos and event, which\n * events a person may post to, opening an event's gallery, and the two notices.\n */\nimport { EntityManager, In } from 'typeorm'\n\nimport { Attachment } from '@things-factory/attachment-base'\nimport { checkPermission, getDomainAssignees, User, UserStatus } from '@things-factory/auth-base'\nimport { Attendee, Event } from '@things-factory/calendar'\nimport { translatorFor } from '@things-factory/i18n-base/translator'\nimport { noticeLinkOf, sendNoticeWhenCommitted, type Notice } from '@things-factory/notification'\nimport { getRepository } from '@things-factory/shell'\n\nimport { GalleryEvent, GalleryLike, GalleryPost } from './gallery'\nimport {\n firstPhotoReceivers,\n firstPhotoWords,\n galleryAddressOf,\n hiddenWords,\n seesPost,\n type Say,\n type Viewer\n} from './gallery-rules'\n\n/** The photos of a post hang on it under this `refType` (attachment-base). */\nexport const GALLERY_REF_TYPE = 'Gallery Post'\n\nconst isId = (id?: string | null) => !!id && /^[0-9a-f-]{36}$/i.test(id)\n\nasync function holds(context: any, category: string, privilege: string, key: string): Promise<boolean> {\n const state = context?.state ?? {}\n const { domain, user, unsafeIP, prohibitedPrivileges } = state\n if (!domain || !user) return false\n /* Asked once per request - a list asks it for each row. */\n state[key] ??= checkPermission(\n { category, privilege, owner: true } as any,\n user,\n domain,\n unsafeIP,\n prohibitedPrivileges\n ).then(Boolean)\n return await state[key]\n}\n\n/** Whether the request moderates the gallery - the module's one task, `gallery.moderation`. */\nexport const isModerator = (context: any) => holds(context, 'gallery', 'mutation', '__galleryModerator')\n\n/** Whether the request reads the domain's whole calendar. */\nconst readsCalendar = (context: any) => holds(context, 'calendar', 'query', '__galleryCalendarReader')\n\n/** The request's person as a post's viewer - asked once per request. */\nexport async function viewerOf(context: any): Promise<Viewer> {\n const state = context.state\n if (!state.__galleryViewer) {\n const people = await getDomainAssignees(state.domain, state.tx)\n state.__galleryViewer = {\n userId: state.user.id,\n moderator: await isModerator(context),\n activePeople: new Set(people.map(one => one.id))\n }\n }\n return state.__galleryViewer\n}\n\n/** The post as the request may see it, or nothing - one answer for \"none\" and \"not for you\". */\nexport async function visiblePost(id: string, context: any, tx?: EntityManager): Promise<GalleryPost | undefined> {\n const { domain, user } = context?.state ?? {}\n if (!isId(id) || !domain || !user) return undefined\n const post = await getRepository(GalleryPost, tx).findOne({ where: { id, domain: { id: domain.id } } as any })\n if (!post) return undefined\n return seesPost(post, await viewerOf(context)) ? post : undefined\n}\n\n/** The photos of each post, in the order they were added. */\nexport async function photosOf(\n postIds: string[],\n domainId: string,\n tx?: EntityManager\n): Promise<Map<string, Attachment[]>> {\n const out = new Map<string, Attachment[]>()\n if (!postIds.length) return out\n const rows = await getRepository(Attachment, tx).find({\n where: { domain: { id: domainId }, refType: GALLERY_REF_TYPE, refBy: In(postIds) } as any,\n order: { createdAt: 'ASC' } as any\n })\n for (const one of rows) out.set(one.refBy!, [...(out.get(one.refBy!) ?? []), one])\n return out\n}\n\n/** The name, time and place of each event. */\nexport async function eventsOf(eventIds: string[], domainId: string, tx?: EntityManager): Promise<Map<string, Event>> {\n const ids = [...new Set(eventIds.filter(isId))]\n if (!ids.length) return new Map()\n const rows = await getRepository(Event, tx).find({ where: { id: In(ids), domain: { id: domainId } } as any })\n return new Map(rows.map(one => [one.id, one]))\n}\n\n/** Puts on each post what its fields answer from - who posted it, its photos, its event and whether the request's person likes it. */\nexport async function decorate(posts: GalleryPost[], context: any): Promise<GalleryPost[]> {\n const { domain, user, tx } = context.state\n const ids = posts.map(one => one.id)\n const photos = await photosOf(ids, domain.id, tx)\n const events = await eventsOf(\n posts.map(one => one.eventId!),\n domain.id,\n tx\n )\n const liked = ids.length\n ? await getRepository(GalleryLike, tx).find({ where: { post: { id: In(ids) }, user: { id: user.id } } as any })\n : []\n const likedIds = new Set(liked.map(one => one.postId))\n const creatorIds = [...new Set(posts.map(one => one.creatorId).filter(Boolean))]\n const creators = new Map(\n (creatorIds.length ? await getRepository(User, tx).find({ where: { id: In(creatorIds) } as any }) : []).map(one => [\n one.id,\n one\n ])\n )\n for (const one of posts as any[]) {\n one.__creator = creators.get(one.creatorId) ?? null\n one.__photos = photos.get(one.id) ?? []\n one.__event = one.eventId ? (events.get(one.eventId) ?? null) : null\n one.__liked = likedIds.has(one.id)\n }\n return posts\n}\n\n/** Whether the event's gallery is open. */\nexport async function isOpenEvent(eventId: string, domainId: string, tx?: EntityManager): Promise<boolean> {\n return !!(await getRepository(GalleryEvent, tx).findOne({\n where: { domain: { id: domainId }, event: { id: eventId } } as any\n }))\n}\n\n/**\n * Whether the request's person may post to the event: its gallery is open, or they see the event - they are named on\n * it or responsible for it, or they read the whole calendar. An event they cannot see takes no photo (판정 1).\n */\nexport async function maySeeEvent(eventId: string, context: any, tx?: EntityManager): Promise<Event | undefined> {\n const { domain, user } = context.state\n if (!isId(eventId)) return undefined\n const event = await getRepository(Event, tx).findOne({ where: { id: eventId, domain: { id: domain.id } } as any })\n if (!event) return undefined\n if (event.organizerId === user.id) return event\n if (await isOpenEvent(eventId, domain.id, tx)) return event\n if (\n await getRepository(Attendee, tx).findOne({\n where: { domain: { id: domain.id }, event: { id: eventId }, user: { id: user.id } } as any\n })\n )\n return event\n return (await readsCalendar(context)) ? event : undefined\n}\n\n/** The events the person may post to that overlap [from, to): their own, the open ones, and all when they read the calendar. */\nexport async function eventsSeenBetween(context: any, from: Date, to: Date, tx?: EntityManager): Promise<Event[]> {\n const { domain, user } = context.state\n const qb = getRepository(Event, tx)\n .createQueryBuilder('E')\n .where('E.domain = :domain', { domain: domain.id })\n .andWhere('E.startAt < :to AND E.endAt > :from', { from, to })\n if (!(await readsCalendar(context))) {\n const named = await getRepository(Attendee, tx).find({\n where: { domain: { id: domain.id }, user: { id: user.id } } as any\n })\n const open = await getRepository(GalleryEvent, tx).find({ where: { domain: { id: domain.id } } as any })\n const ids = [...new Set([...named.map(one => one.eventId), ...open.map(one => one.eventId)].filter(Boolean))]\n qb.andWhere(ids.length ? '(E.organizer = :me OR E.id IN (:...ids))' : 'E.organizer = :me', { me: user.id, ids })\n }\n return await qb.orderBy('E.startAt', 'DESC').take(50).getMany()\n}\n\n/** Opens the event's gallery, once. */\nexport async function openEvent(eventId: string, context: any, tx: EntityManager): Promise<void> {\n const { domain, user } = context.state\n if (await isOpenEvent(eventId, domain.id, tx)) return\n await getRepository(GalleryEvent, tx).save({ domain, event: { id: eventId }, creator: user, updater: user } as any)\n}\n\n/** The sentences in `lng` from this module's translations, the English one where `lng` has none. */\nconst sayIn =\n (lng: string): Say =>\n (key, english, params = {}) =>\n translatorFor(lng)(key, {\n ...params,\n defaultValue: english.replace(/\\{(\\w+)\\}/g, (_, name) => String(params[name] ?? ''))\n })\n\n/** The people to tell, as notification takes them - only those who can sign in. */\nasync function receiversOf(userIds: string[], tx?: EntityManager) {\n if (!userIds.length) return []\n const people = await getRepository(User, tx).find({ where: { id: In(userIds) } as any })\n return people\n .filter(one => one.status === UserStatus.ACTIVATED)\n .map(one => ({ id: one.id, email: one.email, locale: (one as any).locale }))\n}\n\nfunction tell(context: any, notice: Omit<Notice, 'link'>): void {\n sendNoticeWhenCommitted(context, { ...notice, link: noticeLinkOf(context, notice.address) } as Notice)\n}\n\n/**\n * When the post is the event's first, tells the people named on the event - everyone of the domain when it names\n * nobody - that its photos are up (decision 6). Once per event: a later post is not the first.\n */\nexport async function tellFirstPhoto(context: any, post: GalleryPost, eventId: string): Promise<void> {\n const { domain, user, tx } = context.state\n const others = await getRepository(GalleryPost, tx)\n .createQueryBuilder('P')\n .where('P.domain = :domain AND P.event = :event AND P.id != :id', {\n domain: domain.id,\n event: eventId,\n id: post.id\n })\n .withDeleted()\n .getCount()\n if (others) return\n const event = await getRepository(Event, tx).findOne({ where: { id: eventId } as any })\n if (!event) return\n const attendees = await getRepository(Attendee, tx).find({\n where: { domain: { id: domain.id }, event: { id: eventId } } as any\n })\n const members = attendees.some(one => one.userId) ? [] : (await getDomainAssignees(domain, tx)).map(one => one.id)\n const receivers = await receiversOf(\n firstPhotoReceivers(attendees.map(one => one.userId!).filter(Boolean), members, user.id),\n tx\n )\n if (!receivers.length) return\n tell(context, {\n type: 'gallery',\n receivers,\n words: lng => firstPhotoWords(event, user.name ?? '', post.caption, sayIn(lng)),\n address: galleryAddressOf({ eventId }),\n label: `gallery first-photo ${eventId}`,\n /* Photos are no news for the inbox of another app - the app and push carry it, mail only where the domain turned it on. */\n channels: { email: false }\n })\n}\n\n/** Tells the owner that a moderator hid their post, and why (decision 5). */\nexport async function tellHidden(context: any, post: GalleryPost, reason: string): Promise<void> {\n if (!post.creatorId || post.creatorId === context.state.user.id) return\n const receivers = await receiversOf([post.creatorId], context.state.tx)\n if (!receivers.length) return\n tell(context, {\n type: 'gallery',\n level: 'warn',\n receivers,\n words: lng => hiddenWords(reason, sayIn(lng)),\n address: galleryAddressOf({ postId: post.id }),\n label: `gallery hidden ${post.id}`,\n channels: { email: false }\n })\n}\n"]}
@@ -1,65 +0,0 @@
1
- import { GalleryPost, GallerySpace } from './gallery';
2
- export declare class GalleryPhoto {
3
- id: string;
4
- name?: string;
5
- thumbnail?: string;
6
- fullpath: string;
7
- mimetype?: string;
8
- }
9
- /** What everyone of the domain sees of an event a post hangs on - name, time and place, never its people (ADR-0165 사용자 판정 1). */
10
- export declare class GalleryEventFacts {
11
- id: string;
12
- name: string;
13
- startAt: Date;
14
- endAt: Date;
15
- location?: string;
16
- }
17
- export declare class GalleryEventCard extends GalleryEventFacts {
18
- postCount: number;
19
- cover?: GalleryPhoto;
20
- }
21
- export declare class GalleryEventChoice extends GalleryEventFacts {
22
- near: boolean;
23
- }
24
- export declare class GalleryTagCount {
25
- tag: string;
26
- count: number;
27
- }
28
- export declare class GalleryPerson {
29
- id: string;
30
- name?: string;
31
- }
32
- export declare class GalleryPostList {
33
- items: GalleryPost[];
34
- total: number;
35
- }
36
- export declare class GallerySummary {
37
- fresh: number;
38
- }
39
- export declare class GalleryLikeState {
40
- id: string;
41
- likeCount: number;
42
- liked: boolean;
43
- }
44
- export declare class GalleryPostInput {
45
- space?: GallerySpace;
46
- shared?: boolean;
47
- caption?: string;
48
- takenAt?: Date;
49
- tags?: string[];
50
- eventId?: string;
51
- }
52
- export declare class GalleryFilter {
53
- space?: GallerySpace;
54
- eventId?: string;
55
- tag?: string;
56
- authorId?: string;
57
- mine?: boolean;
58
- everyone?: boolean;
59
- }
60
- export declare class GalleryEventInput {
61
- name: string;
62
- startAt: Date;
63
- endAt: Date;
64
- location?: string;
65
- }
@@ -1,239 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GalleryEventInput = exports.GalleryFilter = exports.GalleryPostInput = exports.GalleryLikeState = exports.GallerySummary = exports.GalleryPostList = exports.GalleryPerson = exports.GalleryTagCount = exports.GalleryEventChoice = exports.GalleryEventCard = exports.GalleryEventFacts = exports.GalleryPhoto = void 0;
4
- const tslib_1 = require("tslib");
5
- const type_graphql_1 = require("type-graphql");
6
- const gallery_1 = require("./gallery");
7
- let GalleryPhoto = class GalleryPhoto {
8
- };
9
- exports.GalleryPhoto = GalleryPhoto;
10
- tslib_1.__decorate([
11
- (0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'The attachment id of the photo.' }),
12
- tslib_1.__metadata("design:type", String)
13
- ], GalleryPhoto.prototype, "id", void 0);
14
- tslib_1.__decorate([
15
- (0, type_graphql_1.Field)({ nullable: true, description: 'The file name.' }),
16
- tslib_1.__metadata("design:type", String)
17
- ], GalleryPhoto.prototype, "name", void 0);
18
- tslib_1.__decorate([
19
- (0, type_graphql_1.Field)({ nullable: true, description: 'A small picture of it, usable as an image source.' }),
20
- tslib_1.__metadata("design:type", String)
21
- ], GalleryPhoto.prototype, "thumbnail", void 0);
22
- tslib_1.__decorate([
23
- (0, type_graphql_1.Field)({ description: 'Where the photo itself is read.' }),
24
- tslib_1.__metadata("design:type", String)
25
- ], GalleryPhoto.prototype, "fullpath", void 0);
26
- tslib_1.__decorate([
27
- (0, type_graphql_1.Field)({ nullable: true, description: 'The image type.' }),
28
- tslib_1.__metadata("design:type", String)
29
- ], GalleryPhoto.prototype, "mimetype", void 0);
30
- exports.GalleryPhoto = GalleryPhoto = tslib_1.__decorate([
31
- (0, type_graphql_1.ObjectType)({ description: 'One photo of a gallery post.' })
32
- ], GalleryPhoto);
33
- /** What everyone of the domain sees of an event a post hangs on - name, time and place, never its people (ADR-0165 사용자 판정 1). */
34
- let GalleryEventFacts = class GalleryEventFacts {
35
- };
36
- exports.GalleryEventFacts = GalleryEventFacts;
37
- tslib_1.__decorate([
38
- (0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'The calendar event id.' }),
39
- tslib_1.__metadata("design:type", String)
40
- ], GalleryEventFacts.prototype, "id", void 0);
41
- tslib_1.__decorate([
42
- (0, type_graphql_1.Field)({ description: 'The event name.' }),
43
- tslib_1.__metadata("design:type", String)
44
- ], GalleryEventFacts.prototype, "name", void 0);
45
- tslib_1.__decorate([
46
- (0, type_graphql_1.Field)({ description: 'When it starts.' }),
47
- tslib_1.__metadata("design:type", Date)
48
- ], GalleryEventFacts.prototype, "startAt", void 0);
49
- tslib_1.__decorate([
50
- (0, type_graphql_1.Field)({ description: 'When it ends.' }),
51
- tslib_1.__metadata("design:type", Date)
52
- ], GalleryEventFacts.prototype, "endAt", void 0);
53
- tslib_1.__decorate([
54
- (0, type_graphql_1.Field)({ nullable: true, description: 'Where it takes place.' }),
55
- tslib_1.__metadata("design:type", String)
56
- ], GalleryEventFacts.prototype, "location", void 0);
57
- exports.GalleryEventFacts = GalleryEventFacts = tslib_1.__decorate([
58
- (0, type_graphql_1.ObjectType)({ description: 'The name, time and place of a calendar event - what the gallery shows of it.' })
59
- ], GalleryEventFacts);
60
- let GalleryEventCard = class GalleryEventCard extends GalleryEventFacts {
61
- };
62
- exports.GalleryEventCard = GalleryEventCard;
63
- tslib_1.__decorate([
64
- (0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'How many posts the viewer sees in it.' }),
65
- tslib_1.__metadata("design:type", Number)
66
- ], GalleryEventCard.prototype, "postCount", void 0);
67
- tslib_1.__decorate([
68
- (0, type_graphql_1.Field)(type => GalleryPhoto, {
69
- nullable: true,
70
- description: 'The photo shown for it - the first of its most liked post.'
71
- }),
72
- tslib_1.__metadata("design:type", GalleryPhoto)
73
- ], GalleryEventCard.prototype, "cover", void 0);
74
- exports.GalleryEventCard = GalleryEventCard = tslib_1.__decorate([
75
- (0, type_graphql_1.ObjectType)({ description: 'An event whose gallery is open, with how many posts it holds and the photo shown for it.' })
76
- ], GalleryEventCard);
77
- let GalleryEventChoice = class GalleryEventChoice extends GalleryEventFacts {
78
- };
79
- exports.GalleryEventChoice = GalleryEventChoice;
80
- tslib_1.__decorate([
81
- (0, type_graphql_1.Field)({ description: 'Whether it is near when the photo was taken.' }),
82
- tslib_1.__metadata("design:type", Boolean)
83
- ], GalleryEventChoice.prototype, "near", void 0);
84
- exports.GalleryEventChoice = GalleryEventChoice = tslib_1.__decorate([
85
- (0, type_graphql_1.ObjectType)({ description: 'An event offered for a photo.' })
86
- ], GalleryEventChoice);
87
- let GalleryTagCount = class GalleryTagCount {
88
- };
89
- exports.GalleryTagCount = GalleryTagCount;
90
- tslib_1.__decorate([
91
- (0, type_graphql_1.Field)({ description: 'The tag, without the # mark.' }),
92
- tslib_1.__metadata("design:type", String)
93
- ], GalleryTagCount.prototype, "tag", void 0);
94
- tslib_1.__decorate([
95
- (0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'How many posts hold it.' }),
96
- tslib_1.__metadata("design:type", Number)
97
- ], GalleryTagCount.prototype, "count", void 0);
98
- exports.GalleryTagCount = GalleryTagCount = tslib_1.__decorate([
99
- (0, type_graphql_1.ObjectType)({ description: 'A tag and how many posts hold it.' })
100
- ], GalleryTagCount);
101
- let GalleryPerson = class GalleryPerson {
102
- };
103
- exports.GalleryPerson = GalleryPerson;
104
- tslib_1.__decorate([
105
- (0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'User id.' }),
106
- tslib_1.__metadata("design:type", String)
107
- ], GalleryPerson.prototype, "id", void 0);
108
- tslib_1.__decorate([
109
- (0, type_graphql_1.Field)({ nullable: true, description: 'Their name.' }),
110
- tslib_1.__metadata("design:type", String)
111
- ], GalleryPerson.prototype, "name", void 0);
112
- exports.GalleryPerson = GalleryPerson = tslib_1.__decorate([
113
- (0, type_graphql_1.ObjectType)({ description: 'A person, as the gallery names them.' })
114
- ], GalleryPerson);
115
- let GalleryPostList = class GalleryPostList {
116
- };
117
- exports.GalleryPostList = GalleryPostList;
118
- tslib_1.__decorate([
119
- (0, type_graphql_1.Field)(type => [gallery_1.GalleryPost], { description: 'The posts, newest first.' }),
120
- tslib_1.__metadata("design:type", Array)
121
- ], GalleryPostList.prototype, "items", void 0);
122
- tslib_1.__decorate([
123
- (0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'How many posts the narrowing holds.' }),
124
- tslib_1.__metadata("design:type", Number)
125
- ], GalleryPostList.prototype, "total", void 0);
126
- exports.GalleryPostList = GalleryPostList = tslib_1.__decorate([
127
- (0, type_graphql_1.ObjectType)({ description: 'A page of gallery posts.' })
128
- ], GalleryPostList);
129
- let GallerySummary = class GallerySummary {
130
- };
131
- exports.GallerySummary = GallerySummary;
132
- tslib_1.__decorate([
133
- (0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Posts by others since the person last opened the gallery.' }),
134
- tslib_1.__metadata("design:type", Number)
135
- ], GallerySummary.prototype, "fresh", void 0);
136
- exports.GallerySummary = GallerySummary = tslib_1.__decorate([
137
- (0, type_graphql_1.ObjectType)({ description: "What the gallery's menu entry says." })
138
- ], GallerySummary);
139
- let GalleryLikeState = class GalleryLikeState {
140
- };
141
- exports.GalleryLikeState = GalleryLikeState;
142
- tslib_1.__decorate([
143
- (0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'Post id.' }),
144
- tslib_1.__metadata("design:type", String)
145
- ], GalleryLikeState.prototype, "id", void 0);
146
- tslib_1.__decorate([
147
- (0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'How many people like it.' }),
148
- tslib_1.__metadata("design:type", Number)
149
- ], GalleryLikeState.prototype, "likeCount", void 0);
150
- tslib_1.__decorate([
151
- (0, type_graphql_1.Field)({ description: 'Whether the person likes it.' }),
152
- tslib_1.__metadata("design:type", Boolean)
153
- ], GalleryLikeState.prototype, "liked", void 0);
154
- exports.GalleryLikeState = GalleryLikeState = tslib_1.__decorate([
155
- (0, type_graphql_1.ObjectType)({ description: 'A like as it stands after the change.' })
156
- ], GalleryLikeState);
157
- let GalleryPostInput = class GalleryPostInput {
158
- };
159
- exports.GalleryPostInput = GalleryPostInput;
160
- tslib_1.__decorate([
161
- (0, type_graphql_1.Field)(type => gallery_1.GallerySpace, { nullable: true, description: "The company's gallery (default) or the person's own." }),
162
- tslib_1.__metadata("design:type", String)
163
- ], GalleryPostInput.prototype, "space", void 0);
164
- tslib_1.__decorate([
165
- (0, type_graphql_1.Field)({ nullable: true, description: "Shares a post of the own gallery with everyone of the domain; it is the person's alone when not given." }),
166
- tslib_1.__metadata("design:type", Boolean)
167
- ], GalleryPostInput.prototype, "shared", void 0);
168
- tslib_1.__decorate([
169
- (0, type_graphql_1.Field)({ nullable: true, description: 'A short caption, plain text.' }),
170
- tslib_1.__metadata("design:type", String)
171
- ], GalleryPostInput.prototype, "caption", void 0);
172
- tslib_1.__decorate([
173
- (0, type_graphql_1.Field)({ nullable: true, description: 'When the photos were taken; now when not given.' }),
174
- tslib_1.__metadata("design:type", Date)
175
- ], GalleryPostInput.prototype, "takenAt", void 0);
176
- tslib_1.__decorate([
177
- (0, type_graphql_1.Field)(type => [String], { nullable: true, description: 'The tags; a leading # is dropped.' }),
178
- tslib_1.__metadata("design:type", Array)
179
- ], GalleryPostInput.prototype, "tags", void 0);
180
- tslib_1.__decorate([
181
- (0, type_graphql_1.Field)({ nullable: true, description: 'The calendar event the photos are of - only in the company gallery.' }),
182
- tslib_1.__metadata("design:type", String)
183
- ], GalleryPostInput.prototype, "eventId", void 0);
184
- exports.GalleryPostInput = GalleryPostInput = tslib_1.__decorate([
185
- (0, type_graphql_1.InputType)({ description: 'What a gallery post holds besides its photos.' })
186
- ], GalleryPostInput);
187
- let GalleryFilter = class GalleryFilter {
188
- };
189
- exports.GalleryFilter = GalleryFilter;
190
- tslib_1.__decorate([
191
- (0, type_graphql_1.Field)(type => gallery_1.GallerySpace, { nullable: true, description: 'Only this space.' }),
192
- tslib_1.__metadata("design:type", String)
193
- ], GalleryFilter.prototype, "space", void 0);
194
- tslib_1.__decorate([
195
- (0, type_graphql_1.Field)({ nullable: true, description: 'Only the posts of this event.' }),
196
- tslib_1.__metadata("design:type", String)
197
- ], GalleryFilter.prototype, "eventId", void 0);
198
- tslib_1.__decorate([
199
- (0, type_graphql_1.Field)({ nullable: true, description: 'Only the posts holding this tag.' }),
200
- tslib_1.__metadata("design:type", String)
201
- ], GalleryFilter.prototype, "tag", void 0);
202
- tslib_1.__decorate([
203
- (0, type_graphql_1.Field)({ nullable: true, description: "Only this person's posts." }),
204
- tslib_1.__metadata("design:type", String)
205
- ], GalleryFilter.prototype, "authorId", void 0);
206
- tslib_1.__decorate([
207
- (0, type_graphql_1.Field)({ nullable: true, description: "Only the asking person's own posts - their own gallery." }),
208
- tslib_1.__metadata("design:type", Boolean)
209
- ], GalleryFilter.prototype, "mine", void 0);
210
- tslib_1.__decorate([
211
- (0, type_graphql_1.Field)({ nullable: true, description: "Only the posts everyone of the domain sees - the company's and the shared own ones." }),
212
- tslib_1.__metadata("design:type", Boolean)
213
- ], GalleryFilter.prototype, "everyone", void 0);
214
- exports.GalleryFilter = GalleryFilter = tslib_1.__decorate([
215
- (0, type_graphql_1.InputType)({ description: 'How a list of gallery posts is narrowed.' })
216
- ], GalleryFilter);
217
- let GalleryEventInput = class GalleryEventInput {
218
- };
219
- exports.GalleryEventInput = GalleryEventInput;
220
- tslib_1.__decorate([
221
- (0, type_graphql_1.Field)({ description: 'The event name.' }),
222
- tslib_1.__metadata("design:type", String)
223
- ], GalleryEventInput.prototype, "name", void 0);
224
- tslib_1.__decorate([
225
- (0, type_graphql_1.Field)({ description: 'When it starts.' }),
226
- tslib_1.__metadata("design:type", Date)
227
- ], GalleryEventInput.prototype, "startAt", void 0);
228
- tslib_1.__decorate([
229
- (0, type_graphql_1.Field)({ description: 'When it ends.' }),
230
- tslib_1.__metadata("design:type", Date)
231
- ], GalleryEventInput.prototype, "endAt", void 0);
232
- tslib_1.__decorate([
233
- (0, type_graphql_1.Field)({ nullable: true, description: 'Where it takes place.' }),
234
- tslib_1.__metadata("design:type", String)
235
- ], GalleryEventInput.prototype, "location", void 0);
236
- exports.GalleryEventInput = GalleryEventInput = tslib_1.__decorate([
237
- (0, type_graphql_1.InputType)({ description: 'An event made from the gallery.' })
238
- ], GalleryEventInput);
239
- //# sourceMappingURL=gallery-types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gallery-types.js","sourceRoot":"","sources":["../../../server/service/gallery/gallery-types.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'\n\nimport { GalleryPost, GallerySpace } from './gallery'\n\n@ObjectType({ description: 'One photo of a gallery post.' })\nexport class GalleryPhoto {\n @Field(type => ID, { description: 'The attachment id of the photo.' })\n id: string\n\n @Field({ nullable: true, description: 'The file name.' })\n name?: string\n\n @Field({ nullable: true, description: 'A small picture of it, usable as an image source.' })\n thumbnail?: string\n\n @Field({ description: 'Where the photo itself is read.' })\n fullpath: string\n\n @Field({ nullable: true, description: 'The image type.' })\n mimetype?: string\n}\n\n/** What everyone of the domain sees of an event a post hangs on - name, time and place, never its people (ADR-0165 사용자 판정 1). */\n@ObjectType({ description: 'The name, time and place of a calendar event - what the gallery shows of it.' })\nexport class GalleryEventFacts {\n @Field(type => ID, { description: 'The calendar event id.' })\n id: string\n\n @Field({ description: 'The event name.' })\n name: string\n\n @Field({ description: 'When it starts.' })\n startAt: Date\n\n @Field({ description: 'When it ends.' })\n endAt: Date\n\n @Field({ nullable: true, description: 'Where it takes place.' })\n location?: string\n}\n\n@ObjectType({ description: 'An event whose gallery is open, with how many posts it holds and the photo shown for it.' })\nexport class GalleryEventCard extends GalleryEventFacts {\n @Field(type => Int, { description: 'How many posts the viewer sees in it.' })\n postCount: number\n\n @Field(type => GalleryPhoto, {\n nullable: true,\n description: 'The photo shown for it - the first of its most liked post.'\n })\n cover?: GalleryPhoto\n}\n\n@ObjectType({ description: 'An event offered for a photo.' })\nexport class GalleryEventChoice extends GalleryEventFacts {\n @Field({ description: 'Whether it is near when the photo was taken.' })\n near: boolean\n}\n\n@ObjectType({ description: 'A tag and how many posts hold it.' })\nexport class GalleryTagCount {\n @Field({ description: 'The tag, without the # mark.' })\n tag: string\n\n @Field(type => Int, { description: 'How many posts hold it.' })\n count: number\n}\n\n@ObjectType({ description: 'A person, as the gallery names them.' })\nexport class GalleryPerson {\n @Field(type => ID, { description: 'User id.' })\n id: string\n\n @Field({ nullable: true, description: 'Their name.' })\n name?: string\n}\n\n@ObjectType({ description: 'A page of gallery posts.' })\nexport class GalleryPostList {\n @Field(type => [GalleryPost], { description: 'The posts, newest first.' })\n items: GalleryPost[]\n\n @Field(type => Int, { description: 'How many posts the narrowing holds.' })\n total: number\n}\n\n@ObjectType({ description: \"What the gallery's menu entry says.\" })\nexport class GallerySummary {\n @Field(type => Int, { description: 'Posts by others since the person last opened the gallery.' })\n fresh: number\n}\n\n@ObjectType({ description: 'A like as it stands after the change.' })\nexport class GalleryLikeState {\n @Field(type => ID, { description: 'Post id.' })\n id: string\n\n @Field(type => Int, { description: 'How many people like it.' })\n likeCount: number\n\n @Field({ description: 'Whether the person likes it.' })\n liked: boolean\n}\n\n@InputType({ description: 'What a gallery post holds besides its photos.' })\nexport class GalleryPostInput {\n @Field(type => GallerySpace, { nullable: true, description: \"The company's gallery (default) or the person's own.\" })\n space?: GallerySpace\n\n @Field({ nullable: true, description: \"Shares a post of the own gallery with everyone of the domain; it is the person's alone when not given.\" })\n shared?: boolean\n\n @Field({ nullable: true, description: 'A short caption, plain text.' })\n caption?: string\n\n @Field({ nullable: true, description: 'When the photos were taken; now when not given.' })\n takenAt?: Date\n\n @Field(type => [String], { nullable: true, description: 'The tags; a leading # is dropped.' })\n tags?: string[]\n\n @Field({ nullable: true, description: 'The calendar event the photos are of - only in the company gallery.' })\n eventId?: string\n}\n\n@InputType({ description: 'How a list of gallery posts is narrowed.' })\nexport class GalleryFilter {\n @Field(type => GallerySpace, { nullable: true, description: 'Only this space.' })\n space?: GallerySpace\n\n @Field({ nullable: true, description: 'Only the posts of this event.' })\n eventId?: string\n\n @Field({ nullable: true, description: 'Only the posts holding this tag.' })\n tag?: string\n\n @Field({ nullable: true, description: \"Only this person's posts.\" })\n authorId?: string\n\n @Field({ nullable: true, description: \"Only the asking person's own posts - their own gallery.\" })\n mine?: boolean\n\n @Field({ nullable: true, description: \"Only the posts everyone of the domain sees - the company's and the shared own ones.\" })\n everyone?: boolean\n}\n\n@InputType({ description: 'An event made from the gallery.' })\nexport class GalleryEventInput {\n @Field({ description: 'The event name.' })\n name: string\n\n @Field({ description: 'When it starts.' })\n startAt: Date\n\n @Field({ description: 'When it ends.' })\n endAt: Date\n\n @Field({ nullable: true, description: 'Where it takes place.' })\n location?: string\n}\n"]}