aboutsummaryrefslogtreecommitdiff
path: root/devdoc/design-notes.md
blob: b6ea37a0af71b91eee6637e288f30aa901d41a19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
---
title: ldgallery design notes
author: pacien
date: 2020-02-25
---

__Warning: this document is severely outdated.__

---

# ldgallery design notes

_ldgallery_ consists of two main components that are packaged and distributed
together, but are otherwise functionally independent:

* a __compiler__ which turns a collection of pictures and sidecar metadata
  files into their compressed/normalised and aggregated versions respectively,
  and
* a web __viewer__ in the form of a single-page application, rendering the
  output of the compiler as a searchable picture gallery.


## Gallery compiler

### Input

#### Directory structure

The compiler takes a source directory as input which shall contain item
resource files and associated metadata sidecar files.  Those items may be
recursively grouped into multiple levels of sub-directories.

Example source directory structure:

```
example-gallery-source
├── _DSC8808-1.jpg           -- a picture
├── _DSC8808-1.jpg.yaml      -- its associated sidecar metadata file
└── Glacier 3000             -- a directory grouping gallery items
    ├── thumbnail.jpg        -- optional directory thumbnail
    ├── _DSC5475.jpg
    ├── _DSC5475.jpg.yaml
    ├── _DSC5542.jpg
    └── _DSC5542.jpg.yaml
```


#### Metadata sidecar file

Metadata associated to items are stored in YAML sidecar files of the same name,
with the `.yaml` extension appended.  The use of plain text sidecar files allow
for easier editing without any special tool in a unified manner for multiple
types of files (pictures, videos, ebooks, ...).  The metadata contained within
item files are simply ignored.

Tags are given with a group hierarchy separated by `.`, which allows generic
searches as well as implicit disambiguation.

Example metadata sidecar file:

```yaml
title: Some title

date: 2019-12-20T16:51:52+00:00

description: >
  Some multiline description
  that may contain some markdown later.

tags:
  - photographer.someone
  - location.france.paris
  - monochromatic
```

Possible evolutions:

* Fallback values may later be defined for each field, making them optional.
* The description field could be allowed to contain markdown-formatted content,
  which would be rendered by the __viewer__ app.
* Other keys could be added to allow the definition of specific
  transform/compilation/displaying parameters on a particular file.
* Metadata sidecar files could be added for directories as well in some
  `index.yaml` file.


#### Gallery configuration file

The gallery YAML configuration file contains the __compiler__'s and the
__viewer__'s settings in two different sections.

Proposed configuration file, named `gallery.yaml` at the root of the source
directory:

```yaml
compiler:
  galleryName: My Little Gallery
  ignoreFiles: .*\.txt # to ignore text files
  implicitDirectoryTag: false # default

  thumbnailMaxResolution:
    width: 400  # default
    height: 400 # default

  pictureMaxResolution: # or unspecified to copy files as is
    width: 1024
    height: 768

  # format normalisation?
  # item compression?


viewer:
  # TODO: configuration options to be defined
  # separately shown tags and their colours
  # use hash in URL (useful for use without webserver url rewrite)?
```


### Output

#### Directory structure

```
data
├── items                  -- original/normalised item directory
│   ├── _DSC8808-1.jpg
│   └── Glacier 3000
│       ├── _DSC5475.jpg
│       └── _DSC5542.jpg
├── thumbnails             -- item thumbnails directory
│   ├── _DSC8808-1.jpg
│   └── Glacier 3000
│       ├── thumbnail.jpg
│       ├── _DSC5475.jpg
│       └── _DSC5542.jpg
├── index.json             -- content index file
└── viewer.json            -- viewer configuration file
```


#### Viewer configuration file

The content of the `viewer` section of the gallery configuration file is used,
without any transformation by the __compiler__, to generate the `viewer.json`
file located at the root of the output directory.


#### Gallery items index

The __compiler__ generates a global index file `index.json` aggregating the
metadata of all the source sidecar files as a tree of items as described below.
Its root node is a directory item.  The type of each property node is marked by
its `type` field.

Directory items aggregate their tags from the items below it in order to be
displayed in search results.

Resource paths are rooted with respect to the data output directory which
serves as the base path.

Serialised item structure:

```json
{
  "_comment": "common fields",

  "title": "Some title",
  "date": "2019-12-20T16:51:52+00:00",
  "description": "Some multiline description\nthat may contain some markdown later.",

  "tags": [
    "photographer.someone",
    "location.france.paris",
    "monochromatic"
  ],

  "path": "[resource path]",

  "thumbnail": null | {
    "resource": "[resource path]",
    "resolution": {
      "width": 400,
      "height": 200
    }
  },


  "_comment": "type-dependent",

  "properties": {
    "type": "picture",
    "resource": "[resource url]"
  },

  "properties": {
    "type": "other",
    "resource": "[resource url]"
  },

  "properties": {
    "type": "directory",
    "items": [ { "_comment": "item objects..." } ]
  }
}
```


#### Normalised items and thumbnails

Gallery items are normalised and made available in the `items` sub-directory of
the data output directory.  Normalisation consists of optional transcoding and
other transforms as configured by the user in the compiler part of the
`gallery.yaml` configuration file.

Thumbnails are also generated for those items and are placed in the
`thumbnails` sub-directory.  Thumbnails of pictures in particular are resized
using ~~Lanczos~~ (not available) bilinear resampling.  Directory thumbnails
may later be generated by picking or assembling one or multiple of its items,
or defined explicitely by the user.

The structure of the input directory is kept in both those output
sub-directories.  Input item files and directories also keep their original
names.


## Gallery viewer

The __viewer__ is a single-page web application which displays the gallery's
content.

It runs fully on the client's side and remains usable without any back-end.  It
renders the compiled resources from the `data` directory, placed at its root,
generated by the __compiler__.


### URL anchor

The page anchor is updated and used by the application to reflect the state of
its current state in such a way that any view can be shared and loaded back by
copying the URL and its anchor.  It should in particular contain the current
directory or item, as well as the filtering query.


### Directory/collection/grid view

The application starts by showing a grid view of the root directory of the
gallery.

This combined view offers the possiblity to the user to navigate to other items
and to search recursively through the current directory.


#### Directory breadcrumbs

The directory view displays the current directory path, with links allowing the
user to navigate into parent ones.

```
Gallery / Some directory / Sub-directory
```


#### Filering query

A query field allows the user to search through and filter the items of the
current directory and its sibling items recursively.  This search field allows
restriction on tags in a hierarchical manner.  It should feature some sort of
autocompletion, as well as an adjacent list of tags that are available for
filtering.  Positive as well as negative filtering should be possible, allowing
the user to exclude some tags from the search results.

For instance, the query `france -chessy` should match an item tagged with
`location.france.paris`, but not `location.france.chessy`.

The search is performed on the client side, either by scanning the item tree or
with the use on some client-side indexer such as [Elasticlunr].

In addition to tag-based filtering, full-text search on the `title` and
`description` could later be added by leveraging such indexer.

[Elasticlunr]: http://elasticlunr.com/


#### Thumbnail grid

The content of a directory are displayed as a grid of thumbnails which allows
to navigate through sub-directories and to view items.

By default, the content is rendered in the same ordered as listed in
`index.json`.  The user could later be presented with a menu allowing to sort
those items by name, date for example.


### Item view

Items other than directories are displayed by this view, making use of most of
the screen space to render the element.

This view should as well display the title, description, date, tags and other
information associated to the item.  Tags in particular are displayed in
a grouped manner as determined in `index.json`.

It should be possible to navigate between items of the same directory as the
current one through a thumbnail reel and previous/next links.