PWA capabilities alpha

pull/7/head
Toni Melisma 3 years ago
parent e598cbe85a
commit 2990ed0467
No known key found for this signature in database
GPG Key ID: FFF9A7EDDEA34756

@ -7,11 +7,16 @@ all: deps test build
deps:
$(GO) get ./...
build:
$(GO) build -o bin/fastgallery cmd/fastgallery/main.go
test:
$(GO) test -v ./...
build:
$(GO) build -o bin/fastgallery cmd/fastgallery/main.go
testgallery: build
rm -rf testing/gallery/
rm -f /tmp/fastgallery.log
bin/fastgallery --log /tmp/fastgallery.log --cleanup testing/source/ testing/gallery/
clean:
rm bin/fastgallery

@ -2,11 +2,12 @@
"short_name": "{{ .Shortname }}",
"start_url": "./",
"icons": [
{{ range .Icons }}
{{ range $i, $e := .Icons }}
{{ if $i }},{{ end }}
{
"src": "{ .Src }",
"sizes": "{ .Size }",
"type": "{ .Type }"
"src": "{{ .Src }}",
"sizes": "{{ .Size }}",
"type": "{{ .Type }}"
}
{{ end }}
],

@ -8,7 +8,9 @@ import (
"os"
"os/exec"
"os/signal"
"path"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
@ -126,6 +128,7 @@ type directory struct {
}
// htmlData struct is loaded with all the information required to generate the html from template
// TODO refactor structure inside only function where its used
type htmlData struct {
Title string
Subdirectories []string
@ -629,6 +632,36 @@ func copyFile(source string, destination string) {
}
*/
// getIconSize returns a square size (e.g. 48x48) of an icon based on its filename
// Icon filename must have a substring starting with a string of numbers followed by a consequential
// letter x and a string of more numbers
func getIconSize(iconPath string) (size string, err error) {
iconPath = path.Base(iconPath)
re := regexp.MustCompile(`[0-9]+x[0-9]+`)
size = re.FindString(iconPath)
if size == "" {
err = errors.New("size not found in path: " + iconPath)
return size, err
}
return size, nil
}
// getIconType returns icon file format type (e.g. image/png) of an icon based on its filename
func getIconType(iconPath string) (filetype string, err error) {
iconPath = path.Base(iconPath)
switch filepath.Ext(iconPath) {
case ".png":
return "image/png", nil
}
err = errors.New("could not decide icon filetype: " + iconPath)
return "", err
}
// createPWAManifest creates a customized manifest.json for a PWA if PWA url is supplied in args
func createPWAManifest(gallery directory, source directory, dryRun bool, config configuration) {
// TODO Fill in data structure, load template and execute it
@ -636,6 +669,84 @@ func createPWAManifest(gallery directory, source directory, dryRun bool, config
// TODO Add manifest link to HTMLs
// TODO Add apple-touch-icon to HTML
// TODO register service worker in HTML, add manifest and apple-touch-icon links to head
var PWAData = struct {
Shortname string
Icons []struct {
Src string
Size string
Type string
}
}{
Shortname: source.name,
}
assetDirectoryListing, err := assets.ReadDir(config.assets.assetsDir)
if err != nil {
log.Println("couldn't open embedded assets:", err.Error())
exit(1)
}
re := regexp.MustCompile(`^icon`)
for _, entry := range assetDirectoryListing {
if !entry.IsDir() {
filename := filepath.Base(entry.Name())
// check if asset filename starts with the string "icon"
if re.MatchString(filename) {
iconSize, err := getIconSize(filename)
if err != nil {
log.Println("couldn't define icon size:", err.Error())
exit(1)
}
iconType, err := getIconType(filename)
if err != nil {
log.Println("couldn't define icon type:", err.Error())
exit(1)
}
PWAData.Icons = append(PWAData.Icons, struct {
Src string
Size string
Type string
}{
Src: filename,
Size: iconSize,
Type: iconType,
})
}
}
}
manifestFilePath := filepath.Join(gallery.absPath, config.assets.manifestFile)
if dryRun {
log.Println("Would create web app manifest file:", manifestFilePath)
} else {
templatePath := filepath.Join(config.assets.assetsDir, config.assets.manifestTemplate)
cookedTemplate, err := template.ParseFS(assets, templatePath)
if err != nil {
log.Println("couldn't parse manifest template", templatePath, ":", err.Error())
exit(1)
}
manifestFileHandle, err := os.Create(manifestFilePath)
if err != nil {
log.Println("couldn't create manifest file", manifestFilePath, ":", err.Error())
exit(1)
}
err = cookedTemplate.Execute(manifestFileHandle, PWAData)
if err != nil {
log.Println("couldn't execute manifest template", manifestFilePath, ":", err.Error())
exit(1)
}
manifestFileHandle.Sync()
manifestFileHandle.Close()
log.Println("Created manifest file:", manifestFilePath)
}
}
// copyRootAssets copies all the embedded assets to the root directory of the gallery
@ -1199,12 +1310,6 @@ func main() {
// Check which source media exists in gallery
compareDirectoryTrees(&source, &gallery, config)
// Copy updated web assets (JS, CSS, icons, etc) into gallery root
copyRootAssets(gallery, args.DryRun, config)
// Copy PWA web manifest and fill-in relevant details
createPWAManifest(gallery, source, args.DryRun, config)
// If there are changes in the source, update the media files
newSourceFiles := countChanges(source, config)
@ -1230,6 +1335,12 @@ func main() {
defer vips.Shutdown()
}
// Copy updated web assets (JS, CSS, icons, etc) into gallery root
copyRootAssets(gallery, args.DryRun, config)
// Copy PWA web manifest and fill-in relevant details
createPWAManifest(gallery, source, args.DryRun, config)
// Handle ctrl-C or other signals
setupSignalHandler()

@ -399,6 +399,38 @@ func testTransformFileAndVideo(t *testing.T) {
assert.FileExists(t, testJob.originalFilepath)
}
func TestGetIconSize(t *testing.T) {
iconSize, err := getIconSize("/tmp/icon-48x48.png")
assert.NoError(t, err)
assert.EqualValues(t, "48x48", iconSize)
iconSize, err = getIconSize("test192x192-apple.svg")
assert.NoError(t, err)
assert.EqualValues(t, "192x192", iconSize)
iconSize, err = getIconSize("test-xicon-64x64.ico")
assert.NoError(t, err)
assert.EqualValues(t, "64x64", iconSize)
iconSize, err = getIconSize("test-xicon.ico")
assert.Error(t, err)
assert.EqualValues(t, "", iconSize)
}
func TestGetIconType(t *testing.T) {
iconType, err := getIconType("/tmp/icon-48x48.png")
assert.NoError(t, err)
assert.EqualValues(t, "image/png", iconType)
iconType, err = getIconType("icon-48x48.png")
assert.NoError(t, err)
assert.EqualValues(t, "image/png", iconType)
iconType, err = getIconType("icon-48x48.jpg")
assert.Error(t, err)
assert.EqualValues(t, "", iconType)
}
// TODO tests for
// isDirectory with symlinked dir
// isSymlinkDir

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/2020-05-22 16.41.02.heic

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/2021-01-01 17.11.35.heic

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/2021-01-02 23.51.34.mp4

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/2021-02-22 15.36.43-1.heic

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/2021-02-25 15.40.44.png

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/_DSC9363_DxO.jpg

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/_DSC9439.jpg

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/cranes.jpg

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/dog.heic

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/panorama.heic

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/screenshot.png

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/street.jpg

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/tablet.heic

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/video.mp4

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@ -32,38 +32,38 @@
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/2020-05-22 16.41.02.jpg" alt="2020-05-22 16.41.02.heic" onclick="changePicture(0);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">2020-05-22 16.41.02.heic</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/cranes.jpg" alt="cranes.jpg" onclick="changePicture(0);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">cranes.jpg</span>
</div>
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/2021-01-01 17.11.35.jpg" alt="2021-01-01 17.11.35.heic" onclick="changePicture(1);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">2021-01-01 17.11.35.heic</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/dog.jpg" alt="dog.heic" onclick="changePicture(1);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">dog.heic</span>
</div>
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/2021-01-02 23.51.34.jpg" alt="2021-01-02 23.51.34.mp4" onclick="changePicture(2);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">2021-01-02 23.51.34.mp4</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/panorama.jpg" alt="panorama.heic" onclick="changePicture(2);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">panorama.heic</span>
</div>
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/2021-02-22 15.36.43-1.jpg" alt="2021-02-22 15.36.43-1.heic" onclick="changePicture(3);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">2021-02-22 15.36.43-1.heic</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/screenshot.jpg" alt="screenshot.png" onclick="changePicture(3);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">screenshot.png</span>
</div>
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/2021-02-25 15.40.44.jpg" alt="2021-02-25 15.40.44.png" onclick="changePicture(4);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">2021-02-25 15.40.44.png</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/street.jpg" alt="street.jpg" onclick="changePicture(4);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">street.jpg</span>
</div>
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/_DSC9363_DxO.jpg" alt="_DSC9363_DxO.jpg" onclick="changePicture(5);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">_DSC9363_DxO.jpg</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/tablet.jpg" alt="tablet.heic" onclick="changePicture(5);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">tablet.heic</span>
</div>
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/_DSC9439.jpg" alt="_DSC9439.jpg" onclick="changePicture(6);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">_DSC9439.jpg</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/video.jpg" alt="video.mp4" onclick="changePicture(6);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">video.mp4</span>
</div>
@ -102,58 +102,58 @@
{
thumbnail: "_thumbnail/2020-05-22 16.41.02.jpg",
fullsize: "_fullsize/2020-05-22 16.41.02.jpg",
original: "_original/2020-05-22 16.41.02.heic",
filename: "2020-05-22 16.41.02.heic"
thumbnail: "_thumbnail/cranes.jpg",
fullsize: "_fullsize/cranes.jpg",
original: "_original/cranes.jpg",
filename: "cranes.jpg"
}
,
{
thumbnail: "_thumbnail/2021-01-01 17.11.35.jpg",
fullsize: "_fullsize/2021-01-01 17.11.35.jpg",
original: "_original/2021-01-01 17.11.35.heic",
filename: "2021-01-01 17.11.35.heic"
thumbnail: "_thumbnail/dog.jpg",
fullsize: "_fullsize/dog.jpg",
original: "_original/dog.heic",
filename: "dog.heic"
}
,
{
thumbnail: "_thumbnail/2021-01-02 23.51.34.jpg",
fullsize: "_fullsize/2021-01-02 23.51.34.mp4",
original: "_original/2021-01-02 23.51.34.mp4",
filename: "2021-01-02 23.51.34.mp4"
thumbnail: "_thumbnail/panorama.jpg",
fullsize: "_fullsize/panorama.jpg",
original: "_original/panorama.heic",
filename: "panorama.heic"
}
,
{
thumbnail: "_thumbnail/2021-02-22 15.36.43-1.jpg",
fullsize: "_fullsize/2021-02-22 15.36.43-1.jpg",
original: "_original/2021-02-22 15.36.43-1.heic",
filename: "2021-02-22 15.36.43-1.heic"
thumbnail: "_thumbnail/screenshot.jpg",
fullsize: "_fullsize/screenshot.jpg",
original: "_original/screenshot.png",
filename: "screenshot.png"
}
,
{
thumbnail: "_thumbnail/2021-02-25 15.40.44.jpg",
fullsize: "_fullsize/2021-02-25 15.40.44.jpg",
original: "_original/2021-02-25 15.40.44.png",
filename: "2021-02-25 15.40.44.png"
thumbnail: "_thumbnail/street.jpg",
fullsize: "_fullsize/street.jpg",
original: "_original/street.jpg",
filename: "street.jpg"
}
,
{
thumbnail: "_thumbnail/_DSC9363_DxO.jpg",
fullsize: "_fullsize/_DSC9363_DxO.jpg",
original: "_original/_DSC9363_DxO.jpg",
filename: "_DSC9363_DxO.jpg"
thumbnail: "_thumbnail/tablet.jpg",
fullsize: "_fullsize/tablet.jpg",
original: "_original/tablet.heic",
filename: "tablet.heic"
}
,
{
thumbnail: "_thumbnail/_DSC9439.jpg",
fullsize: "_fullsize/_DSC9439.jpg",
original: "_original/_DSC9439.jpg",
filename: "_DSC9439.jpg"
thumbnail: "_thumbnail/video.jpg",
fullsize: "_fullsize/video.mp4",
original: "_original/video.mp4",
filename: "video.mp4"
}
]
@ -163,6 +163,8 @@
<script src="feather.min.js"></script>
<script src="serviceWorker.js"></script>
<script>
feather.replace()
</script>

@ -0,0 +1,34 @@
{
"short_name": "source",
"start_url": "./",
"icons": [
{
"src": "icon-180x180.png",
"sizes": "180x180",
"type": "image/png"
},
{
"src": "icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icon-36x36.png",
"sizes": "36x36",
"type": "image/png"
},
{
"src": "icon-48x48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"background_color": "#DDDDDD",
"theme_color": "#111111",
"display": "minimal-ui"
}

@ -0,0 +1,13 @@
self.addEventListener('install', (event) => {
console.log("Service worker installed")
});
self.addEventListener('activate', (event) => {
console.log("Service worker activated")
});
self.addEventListener('fetch', (event) => {
event.respondWith(
fetch(event.request)
);
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/subdir/2021-01-13 18.19.20.heic

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/subdir/2021-02-04 13.46.20.heic

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/subdir/gate.heic

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/subdir/winter.heic

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -39,13 +39,13 @@
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/2021-01-13 18.19.20.jpg" alt="2021-01-13 18.19.20.heic" onclick="changePicture(0);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">2021-01-13 18.19.20.heic</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/gate.jpg" alt="gate.heic" onclick="changePicture(0);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">gate.heic</span>
</div>
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/2021-02-04 13.46.20.jpg" alt="2021-02-04 13.46.20.heic" onclick="changePicture(1);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">2021-02-04 13.46.20.heic</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/winter.jpg" alt="winter.heic" onclick="changePicture(1);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">winter.heic</span>
</div>
@ -84,18 +84,18 @@
{
thumbnail: "_thumbnail/2021-01-13 18.19.20.jpg",
fullsize: "_fullsize/2021-01-13 18.19.20.jpg",
original: "_original/2021-01-13 18.19.20.heic",
filename: "2021-01-13 18.19.20.heic"
thumbnail: "_thumbnail/gate.jpg",
fullsize: "_fullsize/gate.jpg",
original: "_original/gate.heic",
filename: "gate.heic"
}
,
{
thumbnail: "_thumbnail/2021-02-04 13.46.20.jpg",
fullsize: "_fullsize/2021-02-04 13.46.20.jpg",
original: "_original/2021-02-04 13.46.20.heic",
filename: "2021-02-04 13.46.20.heic"
thumbnail: "_thumbnail/winter.jpg",
fullsize: "_fullsize/winter.jpg",
original: "_original/winter.heic",
filename: "winter.heic"
}
]
@ -105,6 +105,8 @@
<script src="../feather.min.js"></script>
<script src="../serviceWorker.js"></script>
<script>
feather.replace()
</script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

@ -1 +0,0 @@
/home/toni/go/src/github.com/tonimelisma/fastgallery/testing/source/subdir/subsubdir/2021-02-17 18.59.30.heic

@ -0,0 +1 @@
/Users/tonimelisma/go/src/github.com/tonimelisma/fastgallery/testing/source/subdir/subsubdir/recorder.heic

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@ -32,8 +32,8 @@
<div class="col-4 col-md-3 col-lg-2 float-left p-md-2 p-lg-3">
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/2021-02-17 18.59.30.jpg" alt="2021-02-17 18.59.30.heic" onclick="changePicture(0);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">2021-02-17 18.59.30.heic</span>
<img class="box border border-gray box-shadow width-fit" src="_thumbnail/recorder.jpg" alt="recorder.heic" onclick="changePicture(0);displayModal(true);">
<span class="px-2 pb-2 width-fit css-truncate css-truncate-target">recorder.heic</span>
</div>
@ -72,10 +72,10 @@
{
thumbnail: "_thumbnail/2021-02-17 18.59.30.jpg",
fullsize: "_fullsize/2021-02-17 18.59.30.jpg",
original: "_original/2021-02-17 18.59.30.heic",
filename: "2021-02-17 18.59.30.heic"
thumbnail: "_thumbnail/recorder.jpg",
fullsize: "_fullsize/recorder.jpg",
original: "_original/recorder.heic",
filename: "recorder.heic"
}
]
@ -85,6 +85,8 @@
<script src="../../feather.min.js"></script>
<script src="../../serviceWorker.js"></script>
<script>
feather.replace()
</script>

Loading…
Cancel
Save