@things-factory/gallery 10.1.234 → 10.1.236
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/client/bootstrap.ts +12 -0
- package/client/components/gallery-saver-setting-let.ts +78 -0
- package/client/components/gallery-show.ts +312 -0
- package/client/components/gallery-uploader.ts +16 -1
- package/client/components/gallery-viewer.ts +17 -4
- package/client/pages/gallery-page.ts +18 -16
- package/client/utils/gallery-api.ts +4 -2
- package/client/utils/gallery-saver.ts +72 -0
- package/dist-client/bootstrap.d.ts +1 -0
- package/dist-client/bootstrap.js +10 -0
- package/dist-client/bootstrap.js.map +1 -1
- package/dist-client/components/gallery-saver-setting-let.d.ts +11 -0
- package/dist-client/components/gallery-saver-setting-let.js +81 -0
- package/dist-client/components/gallery-saver-setting-let.js.map +1 -0
- package/dist-client/components/gallery-show.d.ts +46 -0
- package/dist-client/components/gallery-show.js +316 -0
- package/dist-client/components/gallery-show.js.map +1 -0
- package/dist-client/components/gallery-uploader.d.ts +2 -0
- package/dist-client/components/gallery-uploader.js +20 -1
- package/dist-client/components/gallery-uploader.js.map +1 -1
- package/dist-client/components/gallery-viewer.d.ts +2 -2
- package/dist-client/components/gallery-viewer.js +16 -3
- package/dist-client/components/gallery-viewer.js.map +1 -1
- package/dist-client/pages/gallery-page.d.ts +0 -1
- package/dist-client/pages/gallery-page.js +20 -16
- package/dist-client/pages/gallery-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/gallery-api.d.ts +4 -0
- package/dist-client/utils/gallery-api.js +1 -1
- package/dist-client/utils/gallery-api.js.map +1 -1
- package/dist-client/utils/gallery-saver.d.ts +6 -0
- package/dist-client/utils/gallery-saver.js +69 -0
- package/dist-client/utils/gallery-saver.js.map +1 -0
- package/dist-server/service/gallery/gallery-resolver.js +11 -2
- package/dist-server/service/gallery/gallery-resolver.js.map +1 -1
- package/dist-server/service/gallery/gallery-rules.d.ts +4 -2
- package/dist-server/service/gallery/gallery-rules.js +4 -3
- package/dist-server/service/gallery/gallery-rules.js.map +1 -1
- package/dist-server/service/gallery/gallery-types.d.ts +3 -0
- package/dist-server/service/gallery/gallery-types.js +12 -0
- package/dist-server/service/gallery/gallery-types.js.map +1 -1
- package/dist-server/service/gallery/gallery.d.ts +2 -1
- package/dist-server/service/gallery/gallery.js +7 -2
- package/dist-server/service/gallery/gallery.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -4
- package/server/service/gallery/gallery-resolver.ts +9 -2
- package/server/service/gallery/gallery-rules.ts +5 -4
- package/server/service/gallery/gallery-types.ts +9 -0
- package/server/service/gallery/gallery.ts +7 -2
- package/test/gallery-persistence.test.ts +24 -3
- package/test/gallery-rules.test.ts +10 -4
- package/translations/en.json +15 -2
- package/translations/es.json +15 -2
- package/translations/ja.json +15 -2
- package/translations/ko.json +15 -2
- package/translations/ms.json +15 -2
- package/translations/zh.json +15 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/gallery",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.236",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "dist-client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -38,13 +38,14 @@
|
|
|
38
38
|
"@things-factory/apptool-base": "^10.1.234",
|
|
39
39
|
"@things-factory/attachment-base": "^10.1.234",
|
|
40
40
|
"@things-factory/auth-base": "^10.1.234",
|
|
41
|
-
"@things-factory/calendar": "^10.1.
|
|
41
|
+
"@things-factory/calendar": "^10.1.236",
|
|
42
42
|
"@things-factory/i18n-base": "^10.1.234",
|
|
43
|
-
"@things-factory/notification": "^10.1.
|
|
43
|
+
"@things-factory/notification": "^10.1.236",
|
|
44
|
+
"@things-factory/setting-base": "^10.1.234",
|
|
44
45
|
"@things-factory/shell": "^10.1.234",
|
|
45
46
|
"graphql-tag": "^2.12.6",
|
|
46
47
|
"graphql-upload": "^15.0.2",
|
|
47
48
|
"lit": "^3.1.2"
|
|
48
49
|
},
|
|
49
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "1560112ae8ae5a5d296b4fce1d5a1be05e30e8c2"
|
|
50
51
|
}
|
|
@@ -131,13 +131,14 @@ async function seenPosts(context: ResolverContext) {
|
|
|
131
131
|
const qb = getRepository(GalleryPost).createQueryBuilder('P').where('P.domain = :domain', { domain: domain.id })
|
|
132
132
|
if (!viewer.moderator) qb.andWhere('(P.hiddenAt IS NULL OR P.creator = :me)', { me: user.id })
|
|
133
133
|
const active = [...viewer.activePeople]
|
|
134
|
-
/* The own gallery
|
|
134
|
+
/* The own gallery is its owner's until shared (decision 2), and no longer shown when they left (decision 5). */
|
|
135
135
|
qb.andWhere(
|
|
136
136
|
active.length
|
|
137
|
-
? '(P.space != :personal OR P.creator = :me OR P.creator IN (:...active))'
|
|
137
|
+
? '(P.space != :personal OR P.creator = :me OR (P.shared = :shared AND P.creator IN (:...active)))'
|
|
138
138
|
: '(P.space != :personal OR P.creator = :me)',
|
|
139
139
|
{
|
|
140
140
|
personal: GallerySpace.PERSONAL,
|
|
141
|
+
shared: true,
|
|
141
142
|
me: user.id,
|
|
142
143
|
active
|
|
143
144
|
}
|
|
@@ -164,6 +165,10 @@ export class GalleryResolver {
|
|
|
164
165
|
if (filter?.space) qb.andWhere('P.space = :space', { space: filter.space })
|
|
165
166
|
if (filter?.eventId) qb.andWhere('P.event = :event', { event: filter.eventId })
|
|
166
167
|
if (filter?.authorId) qb.andWhere('P.creator = :author', { author: filter.authorId })
|
|
168
|
+
/* The own gallery is the asker's, known here - the client's profile carries no user id (2026-10-31). */
|
|
169
|
+
if (filter?.mine) qb.andWhere('P.creator = :me', { me: context.state.user.id })
|
|
170
|
+
/* What a shared screen may show - the screen saver (decision 9): never one's own unshared photos. */
|
|
171
|
+
if (filter?.everyone) qb.andWhere('(P.space != :personal OR P.shared = :shared)', { personal: GallerySpace.PERSONAL, shared: true })
|
|
167
172
|
const tag = tagOf(filter?.tag ?? '')
|
|
168
173
|
/* Tags are kept as a JSON list: the quotes bound the word, so 「워크숍」 does not find 「워크숍2026」. */
|
|
169
174
|
if (tag) qb.andWhere('LOWER(P.tags) LIKE :tag', { tag: `%${JSON.stringify(tag.toLowerCase())}%` })
|
|
@@ -291,6 +296,7 @@ export class GalleryResolver {
|
|
|
291
296
|
const post = await getRepository(GalleryPost, tx).save({
|
|
292
297
|
domain,
|
|
293
298
|
space: eventId ? GallerySpace.COMPANY : (input.space ?? GallerySpace.COMPANY),
|
|
299
|
+
shared: !!input.shared,
|
|
294
300
|
caption: input.caption?.trim() || null,
|
|
295
301
|
takenAt: input.takenAt ?? new Date(),
|
|
296
302
|
tags: tagsOf(input.tags),
|
|
@@ -331,6 +337,7 @@ export class GalleryResolver {
|
|
|
331
337
|
: null
|
|
332
338
|
await getRepository(GalleryPost, tx).update(post.id, {
|
|
333
339
|
space: eventId ? GallerySpace.COMPANY : (input.space ?? post.space),
|
|
340
|
+
shared: input.shared ?? post.shared,
|
|
334
341
|
caption: input.caption?.trim() || null,
|
|
335
342
|
takenAt: input.takenAt ?? post.takenAt,
|
|
336
343
|
tags: tagsOf(input.tags),
|
|
@@ -100,16 +100,17 @@ export function tagCounts(
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
export type Viewer = { userId: string; moderator: boolean; activePeople: ReadonlySet<string> }
|
|
103
|
-
export type SeenPost = { space: string; creatorId?: string | null; hiddenAt?: Date | string | null }
|
|
103
|
+
export type SeenPost = { space: string; shared?: boolean | null; creatorId?: string | null; hiddenAt?: Date | string | null }
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
|
-
* Whether the viewer sees the post. Everyone of the domain sees
|
|
107
|
-
*
|
|
106
|
+
* Whether the viewer sees the post. Everyone of the domain sees the company's posts (decision 2) and the own-gallery
|
|
107
|
+
* posts their owner shared (decision 2, 2026-10-31) - a moderator sees no unshared one either. A hidden post is seen by
|
|
108
|
+
* its owner and the moderators; the own gallery of someone who left, by no one else (decision 5).
|
|
108
109
|
*/
|
|
109
110
|
export function seesPost(post: SeenPost, viewer: Viewer): boolean {
|
|
110
111
|
const own = !!post.creatorId && post.creatorId === viewer.userId
|
|
111
112
|
if (post.hiddenAt && !own && !viewer.moderator) return false
|
|
112
|
-
if (post.space === 'PERSONAL' && !own && !viewer.activePeople.has(post.creatorId ?? '')) return false
|
|
113
|
+
if (post.space === 'PERSONAL' && !own && !(post.shared && viewer.activePeople.has(post.creatorId ?? ''))) return false
|
|
113
114
|
return true
|
|
114
115
|
}
|
|
115
116
|
|
|
@@ -107,6 +107,9 @@ export class GalleryPostInput {
|
|
|
107
107
|
@Field(type => GallerySpace, { nullable: true, description: "The company's gallery (default) or the person's own." })
|
|
108
108
|
space?: GallerySpace
|
|
109
109
|
|
|
110
|
+
@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." })
|
|
111
|
+
shared?: boolean
|
|
112
|
+
|
|
110
113
|
@Field({ nullable: true, description: 'A short caption, plain text.' })
|
|
111
114
|
caption?: string
|
|
112
115
|
|
|
@@ -133,6 +136,12 @@ export class GalleryFilter {
|
|
|
133
136
|
|
|
134
137
|
@Field({ nullable: true, description: "Only this person's posts." })
|
|
135
138
|
authorId?: string
|
|
139
|
+
|
|
140
|
+
@Field({ nullable: true, description: "Only the asking person's own posts - their own gallery." })
|
|
141
|
+
mine?: boolean
|
|
142
|
+
|
|
143
|
+
@Field({ nullable: true, description: "Only the posts everyone of the domain sees - the company's and the shared own ones." })
|
|
144
|
+
everyone?: boolean
|
|
136
145
|
}
|
|
137
146
|
|
|
138
147
|
@InputType({ description: 'An event made from the gallery.' })
|
|
@@ -20,7 +20,7 @@ import { User } from '@things-factory/auth-base'
|
|
|
20
20
|
import { Event } from '@things-factory/calendar'
|
|
21
21
|
import { Domain } from '@things-factory/shell'
|
|
22
22
|
|
|
23
|
-
/** Where a post lives.
|
|
23
|
+
/** Where a post lives. The company's is seen by everyone of the domain; the person's own by them, and by everyone once shared. */
|
|
24
24
|
export enum GallerySpace {
|
|
25
25
|
/** The company's - events, workshops and work. */
|
|
26
26
|
COMPANY = 'COMPANY',
|
|
@@ -38,7 +38,7 @@ registerEnumType(GallerySpace, {
|
|
|
38
38
|
@Index('ix_gallery_post_1', (one: GalleryPost) => [one.domain, one.event])
|
|
39
39
|
@Index('ix_gallery_post_2', (one: GalleryPost) => [one.domain, one.creator])
|
|
40
40
|
@ObjectType({
|
|
41
|
-
description:
|
|
41
|
+
description: "A post of the gallery - one or more photos, a short caption and tags; the company's seen by everyone of the domain."
|
|
42
42
|
})
|
|
43
43
|
export class GalleryPost {
|
|
44
44
|
@PrimaryGeneratedColumn('uuid')
|
|
@@ -56,6 +56,11 @@ export class GalleryPost {
|
|
|
56
56
|
@Field(type => GallerySpace, { description: "The company's gallery or the person's own." })
|
|
57
57
|
space: GallerySpace
|
|
58
58
|
|
|
59
|
+
/* A post of the own gallery is the person's alone until they share it (2026-10-31, the user) - private by default. */
|
|
60
|
+
@Column({ default: false })
|
|
61
|
+
@Field({ description: "Whether a post of the person's own gallery is open to everyone of the domain; the company's always is." })
|
|
62
|
+
shared: boolean
|
|
63
|
+
|
|
59
64
|
@Column({ type: 'text', nullable: true })
|
|
60
65
|
@Field({ nullable: true, description: 'A short caption, plain text.' })
|
|
61
66
|
caption?: string
|
|
@@ -152,19 +152,40 @@ async function refusal(promise: Promise<unknown>): Promise<string | undefined> {
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
describe('who sees a post', () => {
|
|
155
|
-
it('★ everyone of the domain sees every post, the newest first', async () => {
|
|
155
|
+
it('★ everyone of the domain sees every shared post, the newest first', async () => {
|
|
156
156
|
await post('kim', { caption: '첫 사진' })
|
|
157
|
-
await post('lee', { caption: '내 고양이', space: 'PERSONAL' })
|
|
157
|
+
await post('lee', { caption: '내 고양이', space: 'PERSONAL', shared: true })
|
|
158
158
|
expect(await listed('mod')).toEqual(['내 고양이', '첫 사진'])
|
|
159
159
|
expect(await listed('kim', { space: 'COMPANY' })).toEqual(['첫 사진'])
|
|
160
160
|
expect(await listed('kim', { authorId: people.lee.id })).toEqual(['내 고양이'])
|
|
161
|
+
/* The own gallery is the asker's own posts, whoever else posted (2026-10-31). */
|
|
162
|
+
expect(await listed('kim', { mine: true })).toEqual(['첫 사진'])
|
|
163
|
+
expect(await listed('lee', { mine: true })).toEqual(['내 고양이'])
|
|
164
|
+
expect(await listed('mod', { mine: true })).toEqual([])
|
|
161
165
|
const [first] = (await doors.galleryPosts({}, 0, 1, as('mod'))).items
|
|
162
166
|
expect((await doors.creator(first))?.name).toBe('lee')
|
|
163
167
|
})
|
|
164
168
|
|
|
169
|
+
it('★ an own-gallery post is for its owner alone until shared - its photo too - and a shared screen shows only what all see', async () => {
|
|
170
|
+
await post('kim', { caption: '회사 사진' })
|
|
171
|
+
const mine = await post('lee', { caption: '내 강아지', space: 'PERSONAL' })
|
|
172
|
+
expect(mine.shared).toBe(false)
|
|
173
|
+
expect(await listed('kim')).toEqual(['회사 사진'])
|
|
174
|
+
expect(await listed('mod', {}, { moderator: true })).toEqual(['회사 사진'])
|
|
175
|
+
expect(await listed('kim', { authorId: people.lee.id })).toEqual([])
|
|
176
|
+
expect(await doors.galleryPost(mine.id, as('kim'))).toBeUndefined()
|
|
177
|
+
expect(await listed('lee')).toEqual(['내 강아지', '회사 사진'])
|
|
178
|
+
/* The screen saver asks for what everyone sees - never the device's person's unshared photos (decision 9). */
|
|
179
|
+
expect(await listed('lee', { everyone: true })).toEqual(['회사 사진'])
|
|
180
|
+
await doors.updateGalleryPost(mine.id, { space: 'PERSONAL', shared: true, caption: '내 강아지', tags: [] }, undefined, undefined, as('lee'))
|
|
181
|
+
expect(await listed('kim')).toEqual(['내 강아지', '회사 사진'])
|
|
182
|
+
expect(await listed('lee', { everyone: true })).toEqual(['내 강아지', '회사 사진'])
|
|
183
|
+
expect((await doors.galleryPost(mine.id, as('kim')))?.caption).toBe('내 강아지')
|
|
184
|
+
})
|
|
185
|
+
|
|
165
186
|
it('★ the own gallery of someone who left goes from view; their company posts stay', async () => {
|
|
166
187
|
await post('left', { caption: '회사 사진' })
|
|
167
|
-
await post('left', { caption: '내 사진', space: 'PERSONAL' })
|
|
188
|
+
await post('left', { caption: '내 사진', space: 'PERSONAL', shared: true })
|
|
168
189
|
await dataSource.getRepository(authBase.User).update(people.left.id, { status: 'inactive' })
|
|
169
190
|
expect(await listed('kim')).toEqual(['회사 사진'])
|
|
170
191
|
})
|
|
@@ -81,9 +81,15 @@ describe('what a post may hold', () => {
|
|
|
81
81
|
describe('who sees a post', () => {
|
|
82
82
|
const viewer = (userId: string, moderator = false) => ({ userId, moderator, activePeople: new Set(['me', 'kim']) })
|
|
83
83
|
|
|
84
|
-
it('everyone of the domain sees a company post and
|
|
84
|
+
it('everyone of the domain sees a company post and what someone here shared of their own gallery', () => {
|
|
85
85
|
expect(seesPost({ space: 'COMPANY', creatorId: 'kim' }, viewer('me'))).toBe(true)
|
|
86
|
-
expect(seesPost({ space: 'PERSONAL', creatorId: 'kim' }, viewer('me'))).toBe(true)
|
|
86
|
+
expect(seesPost({ space: 'PERSONAL', shared: true, creatorId: 'kim' }, viewer('me'))).toBe(true)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('an unshared post of the own gallery is for its owner alone - not even a moderator sees it', () => {
|
|
90
|
+
expect(seesPost({ space: 'PERSONAL', creatorId: 'kim' }, viewer('kim'))).toBe(true)
|
|
91
|
+
expect(seesPost({ space: 'PERSONAL', creatorId: 'kim' }, viewer('me'))).toBe(false)
|
|
92
|
+
expect(seesPost({ space: 'PERSONAL', shared: false, creatorId: 'kim' }, viewer('me', true))).toBe(false)
|
|
87
93
|
})
|
|
88
94
|
|
|
89
95
|
it('a hidden post is seen by its owner and the moderators only', () => {
|
|
@@ -94,8 +100,8 @@ describe('who sees a post', () => {
|
|
|
94
100
|
})
|
|
95
101
|
|
|
96
102
|
it('the own gallery of someone who left is no longer shown; their company posts stay', () => {
|
|
97
|
-
expect(seesPost({ space: 'PERSONAL', creatorId: 'left' }, viewer('me'))).toBe(false)
|
|
98
|
-
expect(seesPost({ space: 'PERSONAL', creatorId: 'left' }, viewer('me', true))).toBe(false)
|
|
103
|
+
expect(seesPost({ space: 'PERSONAL', shared: true, creatorId: 'left' }, viewer('me'))).toBe(false)
|
|
104
|
+
expect(seesPost({ space: 'PERSONAL', shared: true, creatorId: 'left' }, viewer('me', true))).toBe(false)
|
|
99
105
|
expect(seesPost({ space: 'COMPANY', creatorId: 'left' }, viewer('me'))).toBe(true)
|
|
100
106
|
})
|
|
101
107
|
})
|
package/translations/en.json
CHANGED
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
"gallery.text.caption-placeholder": "Add a line or two (optional)",
|
|
44
44
|
"gallery.text.tag-placeholder": "Type like #workshop and press Enter",
|
|
45
45
|
"gallery.text.no-event": "No event",
|
|
46
|
-
"gallery.text.personal-note": "Everyone in the workplace sees your own gallery too.",
|
|
47
46
|
"gallery.text.photos-full": "A post holds up to {count} photos.",
|
|
48
47
|
"gallery.text.photos-skipped": "{count} left out - not photos, or no room.",
|
|
49
48
|
"gallery.text.posted": "Posted.",
|
|
@@ -88,5 +87,19 @@
|
|
|
88
87
|
"gallery.refusal.reason-too-long": "The reason is at most 200 characters.",
|
|
89
88
|
"task.gallery.moderation.name": "Gallery moderation",
|
|
90
89
|
"task.gallery.moderation.description": "Hides posts or shows them again, tidies the tags, and makes events from the gallery.",
|
|
91
|
-
"gallery.text.tag-too-long-typed": "A tag takes up to {max} characters; this one has {length}. Shorten it and add it again."
|
|
90
|
+
"gallery.text.tag-too-long-typed": "A tag takes up to {max} characters; this one has {length}. Shorten it and add it again.",
|
|
91
|
+
"gallery.button.large": "View large",
|
|
92
|
+
"gallery.button.slideshow": "Slideshow",
|
|
93
|
+
"gallery.button.play": "Play",
|
|
94
|
+
"gallery.button.pause": "Pause",
|
|
95
|
+
"gallery.title.saver": "Gallery screen saver",
|
|
96
|
+
"gallery.text.saver-off": "Off",
|
|
97
|
+
"gallery.text.saver-after": "After {minutes} minutes idle",
|
|
98
|
+
"gallery.text.saver-note": "Applies to this device only. Shows company photos and shared personal photos in random order and closes when the mouse or keyboard is used.",
|
|
99
|
+
"gallery.text.show-empty": "No photos to show.",
|
|
100
|
+
"gallery.field.shared": "Who sees it",
|
|
101
|
+
"gallery.text.only-me": "Only me",
|
|
102
|
+
"gallery.text.everyone": "Everyone here",
|
|
103
|
+
"gallery.text.only-me-note": "Only you see it - not the moderators, and not the screen saver.",
|
|
104
|
+
"gallery.text.shared-note": "Everyone in the workplace sees it, and the screen saver shows it."
|
|
92
105
|
}
|
package/translations/es.json
CHANGED
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
"gallery.text.caption-placeholder": "Añade una o dos líneas (opcional)",
|
|
44
44
|
"gallery.text.tag-placeholder": "Escribe como #taller y pulsa Enter",
|
|
45
45
|
"gallery.text.no-event": "Sin evento",
|
|
46
|
-
"gallery.text.personal-note": "Todos en el lugar de trabajo ven también tu galería.",
|
|
47
46
|
"gallery.text.photos-full": "Una publicación admite hasta {count} fotos.",
|
|
48
47
|
"gallery.text.photos-skipped": "Se omitieron {count}: no son fotos o no caben.",
|
|
49
48
|
"gallery.text.posted": "Publicado.",
|
|
@@ -88,5 +87,19 @@
|
|
|
88
87
|
"gallery.refusal.reason-too-long": "El motivo admite hasta 200 caracteres.",
|
|
89
88
|
"task.gallery.moderation.name": "Moderación de la galería",
|
|
90
89
|
"task.gallery.moderation.description": "Oculta publicaciones o las vuelve a mostrar, ordena las etiquetas y crea eventos desde la galería.",
|
|
91
|
-
"gallery.text.tag-too-long-typed": "Una etiqueta admite hasta {max} caracteres; esta tiene {length}. Acórtela y añádala de nuevo."
|
|
90
|
+
"gallery.text.tag-too-long-typed": "Una etiqueta admite hasta {max} caracteres; esta tiene {length}. Acórtela y añádala de nuevo.",
|
|
91
|
+
"gallery.button.large": "Ver en grande",
|
|
92
|
+
"gallery.button.slideshow": "Presentación",
|
|
93
|
+
"gallery.button.play": "Reproducir",
|
|
94
|
+
"gallery.button.pause": "Pausa",
|
|
95
|
+
"gallery.title.saver": "Protector de pantalla de la galería",
|
|
96
|
+
"gallery.text.saver-off": "Desactivado",
|
|
97
|
+
"gallery.text.saver-after": "Tras {minutes} minutos sin actividad",
|
|
98
|
+
"gallery.text.saver-note": "Solo en este dispositivo. Muestra fotos de la empresa y fotos personales compartidas en orden aleatorio y se cierra al usar el ratón o el teclado.",
|
|
99
|
+
"gallery.text.show-empty": "No hay fotos para mostrar.",
|
|
100
|
+
"gallery.field.shared": "Quién lo ve",
|
|
101
|
+
"gallery.text.only-me": "Solo yo",
|
|
102
|
+
"gallery.text.everyone": "Todos aquí",
|
|
103
|
+
"gallery.text.only-me-note": "Solo tú la ves: ni los moderadores ni el protector de pantalla.",
|
|
104
|
+
"gallery.text.shared-note": "Todos en el lugar de trabajo la ven, y el protector de pantalla la muestra."
|
|
92
105
|
}
|
package/translations/ja.json
CHANGED
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
"gallery.text.caption-placeholder": "ひとことどうぞ(任意)",
|
|
44
44
|
"gallery.text.tag-placeholder": "#ワークショップ のように入力して Enter",
|
|
45
45
|
"gallery.text.no-event": "イベントなし",
|
|
46
|
-
"gallery.text.personal-note": "マイギャラリーの写真も職場の全員が見られます。",
|
|
47
46
|
"gallery.text.photos-full": "1件の投稿に写真は{count}枚までです。",
|
|
48
47
|
"gallery.text.photos-skipped": "写真でないか上限のため{count}件を除きました。",
|
|
49
48
|
"gallery.text.posted": "投稿しました。",
|
|
@@ -88,5 +87,19 @@
|
|
|
88
87
|
"gallery.refusal.reason-too-long": "理由は200文字までです。",
|
|
89
88
|
"task.gallery.moderation.name": "ギャラリー管理",
|
|
90
89
|
"task.gallery.moderation.description": "投稿の非表示・再表示、タグの整理、ギャラリーからのイベント作成。",
|
|
91
|
-
"gallery.text.tag-too-long-typed": "タグは{max}文字までです。今は{length}文字です。短くしてもう一度入れてください。"
|
|
90
|
+
"gallery.text.tag-too-long-typed": "タグは{max}文字までです。今は{length}文字です。短くしてもう一度入れてください。",
|
|
91
|
+
"gallery.button.large": "大きく表示",
|
|
92
|
+
"gallery.button.slideshow": "スライドショー",
|
|
93
|
+
"gallery.button.play": "再生",
|
|
94
|
+
"gallery.button.pause": "一時停止",
|
|
95
|
+
"gallery.title.saver": "ギャラリーのスクリーンセーバー",
|
|
96
|
+
"gallery.text.saver-off": "使わない",
|
|
97
|
+
"gallery.text.saver-after": "{minutes}分間操作がないとき",
|
|
98
|
+
"gallery.text.saver-note": "この端末にだけ適用されます。会社の写真と公開された個人の写真をランダムに表示し、マウスやキーボードを使うと閉じます。",
|
|
99
|
+
"gallery.text.show-empty": "表示する写真がありません。",
|
|
100
|
+
"gallery.field.shared": "見る人",
|
|
101
|
+
"gallery.text.only-me": "自分だけ",
|
|
102
|
+
"gallery.text.everyone": "事業所の全員",
|
|
103
|
+
"gallery.text.only-me-note": "自分だけが見ます。管理者にも見えず、スクリーンセーバーにも出ません。",
|
|
104
|
+
"gallery.text.shared-note": "事業所の全員が見て、スクリーンセーバーにも出ます。"
|
|
92
105
|
}
|
package/translations/ko.json
CHANGED
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
"gallery.text.caption-placeholder": "한두 줄 남겨 보세요 (없어도 됩니다)",
|
|
44
44
|
"gallery.text.tag-placeholder": "#워크숍 처럼 넣고 Enter",
|
|
45
45
|
"gallery.text.no-event": "행사 없음",
|
|
46
|
-
"gallery.text.personal-note": "내 갤러리 사진도 사업장 사람 모두가 봅니다.",
|
|
47
46
|
"gallery.text.photos-full": "한 게시물에 사진은 {count}장까지입니다.",
|
|
48
47
|
"gallery.text.photos-skipped": "사진이 아니거나 자리가 없어 {count}개를 빼었습니다.",
|
|
49
48
|
"gallery.text.posted": "올렸습니다.",
|
|
@@ -88,5 +87,19 @@
|
|
|
88
87
|
"gallery.refusal.reason-too-long": "까닭은 200자까지입니다.",
|
|
89
88
|
"task.gallery.moderation.name": "갤러리 관리",
|
|
90
89
|
"task.gallery.moderation.description": "게시물을 숨기거나 다시 보이고, 태그를 정리하고, 갤러리에서 행사를 만든다.",
|
|
91
|
-
"gallery.text.tag-too-long-typed": "태그는 {max}자까지입니다. 지금 {length}자입니다. 줄여서 다시 넣어 주세요."
|
|
90
|
+
"gallery.text.tag-too-long-typed": "태그는 {max}자까지입니다. 지금 {length}자입니다. 줄여서 다시 넣어 주세요.",
|
|
91
|
+
"gallery.button.large": "크게 보기",
|
|
92
|
+
"gallery.button.slideshow": "슬라이드쇼",
|
|
93
|
+
"gallery.button.play": "재생",
|
|
94
|
+
"gallery.button.pause": "일시 정지",
|
|
95
|
+
"gallery.title.saver": "갤러리 화면보호기",
|
|
96
|
+
"gallery.text.saver-off": "사용 안 함",
|
|
97
|
+
"gallery.text.saver-after": "{minutes}분 동안 입력이 없으면",
|
|
98
|
+
"gallery.text.saver-note": "이 기기에만 적용됩니다. 회사 사진과 공개한 개인 사진을 무작위 순서로 보여 주고, 마우스나 키보드를 움직이면 닫힙니다.",
|
|
99
|
+
"gallery.text.show-empty": "보여 줄 사진이 없습니다.",
|
|
100
|
+
"gallery.field.shared": "보는 사람",
|
|
101
|
+
"gallery.text.only-me": "나만 보기",
|
|
102
|
+
"gallery.text.everyone": "사업장 모두",
|
|
103
|
+
"gallery.text.only-me-note": "나만 봅니다. 관리자도 보지 못하고, 화면보호기에도 나오지 않습니다.",
|
|
104
|
+
"gallery.text.shared-note": "사업장 사람 모두가 보고, 화면보호기에도 나옵니다."
|
|
92
105
|
}
|
package/translations/ms.json
CHANGED
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
"gallery.text.caption-placeholder": "Tulis satu dua baris (pilihan)",
|
|
44
44
|
"gallery.text.tag-placeholder": "Taip seperti #bengkel dan tekan Enter",
|
|
45
45
|
"gallery.text.no-event": "Tiada acara",
|
|
46
|
-
"gallery.text.personal-note": "Semua orang di tempat kerja juga melihat galeri anda.",
|
|
47
46
|
"gallery.text.photos-full": "Satu siaran memuatkan sehingga {count} foto.",
|
|
48
47
|
"gallery.text.photos-skipped": "{count} ditinggalkan - bukan foto atau tiada ruang.",
|
|
49
48
|
"gallery.text.posted": "Telah disiarkan.",
|
|
@@ -88,5 +87,19 @@
|
|
|
88
87
|
"gallery.refusal.reason-too-long": "Sebab maksimum 200 aksara.",
|
|
89
88
|
"task.gallery.moderation.name": "Moderasi galeri",
|
|
90
89
|
"task.gallery.moderation.description": "Menyembunyikan atau menunjukkan semula siaran, mengemas tag dan mencipta acara dari galeri.",
|
|
91
|
-
"gallery.text.tag-too-long-typed": "Tag boleh sehingga {max} aksara; tag ini ada {length}. Pendekkan dan tambah semula."
|
|
90
|
+
"gallery.text.tag-too-long-typed": "Tag boleh sehingga {max} aksara; tag ini ada {length}. Pendekkan dan tambah semula.",
|
|
91
|
+
"gallery.button.large": "Lihat besar",
|
|
92
|
+
"gallery.button.slideshow": "Tayangan slaid",
|
|
93
|
+
"gallery.button.play": "Main",
|
|
94
|
+
"gallery.button.pause": "Jeda",
|
|
95
|
+
"gallery.title.saver": "Penyelamat skrin galeri",
|
|
96
|
+
"gallery.text.saver-off": "Mati",
|
|
97
|
+
"gallery.text.saver-after": "Selepas {minutes} minit tanpa aktiviti",
|
|
98
|
+
"gallery.text.saver-note": "Untuk peranti ini sahaja. Memaparkan foto syarikat dan foto peribadi yang dikongsi secara rawak dan tertutup apabila tetikus atau papan kekunci digunakan.",
|
|
99
|
+
"gallery.text.show-empty": "Tiada foto untuk dipaparkan.",
|
|
100
|
+
"gallery.field.shared": "Siapa yang melihat",
|
|
101
|
+
"gallery.text.only-me": "Saya sahaja",
|
|
102
|
+
"gallery.text.everyone": "Semua di sini",
|
|
103
|
+
"gallery.text.only-me-note": "Hanya anda yang melihatnya - bukan moderator, dan tidak dalam penyelamat skrin.",
|
|
104
|
+
"gallery.text.shared-note": "Semua di tempat kerja melihatnya, dan penyelamat skrin memaparkannya."
|
|
92
105
|
}
|
package/translations/zh.json
CHANGED
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
"gallery.text.caption-placeholder": "写一两句(可不填)",
|
|
44
44
|
"gallery.text.tag-placeholder": "输入如 #团建 后按 Enter",
|
|
45
45
|
"gallery.text.no-event": "无活动",
|
|
46
|
-
"gallery.text.personal-note": "我的相册中的照片同样对单位所有人可见。",
|
|
47
46
|
"gallery.text.photos-full": "每个帖子最多 {count} 张照片。",
|
|
48
47
|
"gallery.text.photos-skipped": "已略过 {count} 个(非照片或超出上限)。",
|
|
49
48
|
"gallery.text.posted": "已上传。",
|
|
@@ -88,5 +87,19 @@
|
|
|
88
87
|
"gallery.refusal.reason-too-long": "原因最多 200 字。",
|
|
89
88
|
"task.gallery.moderation.name": "相册管理",
|
|
90
89
|
"task.gallery.moderation.description": "隐藏或重新显示帖子、整理标签、在相册中创建活动。",
|
|
91
|
-
"gallery.text.tag-too-long-typed": "标签最多 {max} 个字符,现在是 {length} 个。请缩短后重新添加。"
|
|
90
|
+
"gallery.text.tag-too-long-typed": "标签最多 {max} 个字符,现在是 {length} 个。请缩短后重新添加。",
|
|
91
|
+
"gallery.button.large": "放大查看",
|
|
92
|
+
"gallery.button.slideshow": "幻灯片",
|
|
93
|
+
"gallery.button.play": "播放",
|
|
94
|
+
"gallery.button.pause": "暂停",
|
|
95
|
+
"gallery.title.saver": "相册屏幕保护",
|
|
96
|
+
"gallery.text.saver-off": "关闭",
|
|
97
|
+
"gallery.text.saver-after": "{minutes}分钟无操作后",
|
|
98
|
+
"gallery.text.saver-note": "仅适用于此设备。随机播放公司照片和公开的个人照片,移动鼠标或按键即关闭。",
|
|
99
|
+
"gallery.text.show-empty": "没有可显示的照片。",
|
|
100
|
+
"gallery.field.shared": "可见范围",
|
|
101
|
+
"gallery.text.only-me": "仅自己",
|
|
102
|
+
"gallery.text.everyone": "所有同事",
|
|
103
|
+
"gallery.text.only-me-note": "只有你能看到,管理员看不到,屏幕保护也不显示。",
|
|
104
|
+
"gallery.text.shared-note": "所有同事都能看到,屏幕保护也会显示。"
|
|
92
105
|
}
|