Use of offset value in the UI (#5)
Added recognition of the offset value in the UI. It will be displayed if available. Caveat: Search will not take offset into account. A new year's picture taken in Sydney the 1st of January 2019 00:15:00 GMT+11, is technically taken in 31st of December 2018 in UTC. Therefore this picture won't show of in seaches where the after: parameter is set to 1st of january 2019. This is both correct and wrong at the same time. UTC-wise it is correct, local time it is not correct. I guess most people would find local time most untuitive, so there is room for improvement of the search. :)
BIN
demo/images/dupl/big_ben_only_time.jpg
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
demo/images/dupl/sydney_opera_house.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
demo/images/timestamps/big_ben.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
demo/images/timestamps/big_ben_no_tsoffset_but_gps_utc.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
demo/images/timestamps/big_ben_only_time.jpg
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
demo/images/timestamps/newyear_london.jpg
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
demo/images/timestamps/newyear_sydney.jpg
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
demo/images/timestamps/sydney_opera_house.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
@ -5,6 +5,7 @@ import {MediaDTOWithThPath, Messenger} from './Messenger';
|
||||
import {backendTexts} from '../../../common/BackendTexts';
|
||||
import {DynamicConfig} from '../../../common/entities/DynamicConfig';
|
||||
import {DefaultMessengers} from '../../../common/entities/job/JobDTO';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
|
||||
export class EmailMessenger extends Messenger<{
|
||||
emailTo: string,
|
||||
@ -69,7 +70,7 @@ export class EmailMessenger extends Messenger<{
|
||||
(media[i].metadata as PhotoMetadata).positionData?.country :
|
||||
((media[i].metadata as PhotoMetadata).positionData?.city ?
|
||||
(media[i].metadata as PhotoMetadata).positionData?.city : '');
|
||||
const caption = (new Date(media[i].metadata.creationDate)).getFullYear() + (location ? ', ' + location : '');
|
||||
const caption = Utils.getFullYear(media[i].metadata.creationDate, media[i].metadata.creationDateOffset) + (location ? ', ' + location : '');
|
||||
attachments.push({
|
||||
filename: media[i].name,
|
||||
path: media[i].thumbnailPath,
|
||||
|
@ -1,286 +1,286 @@
|
||||
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
|
||||
import {Express} from 'express';
|
||||
import {GalleryMWs} from '../middlewares/GalleryMWs';
|
||||
import {RenderingMWs} from '../middlewares/RenderingMWs';
|
||||
import {ThumbnailGeneratorMWs} from '../middlewares/thumbnail/ThumbnailGeneratorMWs';
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
import {ThumbnailSourceType} from '../model/fileaccess/PhotoWorker';
|
||||
import {VersionMWs} from '../middlewares/VersionMWs';
|
||||
import {SupportedFormats} from '../../common/SupportedFormats';
|
||||
import {ServerTimingMWs} from '../middlewares/ServerTimingMWs';
|
||||
import {MetaFileMWs} from '../middlewares/MetaFileMWs';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
|
||||
export class GalleryRouter {
|
||||
public static route(app: Express): void {
|
||||
this.addGetImageIcon(app);
|
||||
this.addGetVideoIcon(app);
|
||||
this.addGetResizedPhoto(app);
|
||||
this.addGetBestFitVideo(app);
|
||||
this.addGetVideoThumbnail(app);
|
||||
this.addGetImage(app);
|
||||
this.addGetVideo(app);
|
||||
this.addGetMetaFile(app);
|
||||
this.addGetBestFitMetaFile(app);
|
||||
this.addRandom(app);
|
||||
this.addDirectoryList(app);
|
||||
this.addDirectoryZip(app);
|
||||
|
||||
this.addSearch(app);
|
||||
this.addAutoComplete(app);
|
||||
}
|
||||
|
||||
protected static addDirectoryList(app: Express): void {
|
||||
app.get(
|
||||
[Config.Server.apiPath + '/gallery/content/:directory(*)', Config.Server.apiPath + '/gallery/', Config.Server.apiPath + '/gallery//'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('directory'),
|
||||
AuthenticationMWs.authorisePath('directory', true),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
GalleryMWs.listDirectory,
|
||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||
GalleryMWs.cleanUpGalleryResults,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
}
|
||||
|
||||
protected static addDirectoryZip(app: Express): void {
|
||||
app.get(
|
||||
[Config.Server.apiPath + '/gallery/zip/:directory(*)'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('directory'),
|
||||
AuthenticationMWs.authorisePath('directory', true),
|
||||
|
||||
// specific part
|
||||
ServerTimingMWs.addServerTiming,
|
||||
GalleryMWs.zipDirectory
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetImage(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Photos.join('|') +
|
||||
'))',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetVideo(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Videos.join('|') +
|
||||
'))',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetBestFitVideo(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Videos.join('|') +
|
||||
'))/bestFit',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
GalleryMWs.loadBestFitVideo,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetMetaFile(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.MetaFiles.join('|') +
|
||||
'))',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetBestFitMetaFile(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.MetaFiles.join('|') +
|
||||
'))/bestFit',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
MetaFileMWs.compressGPX,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addRandom(app: Express): void {
|
||||
app.get(
|
||||
[Config.Server.apiPath + '/gallery/random/:searchQueryDTO'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
GalleryMWs.getRandomImage,
|
||||
GalleryMWs.loadFile,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for serving photo thumbnails and previews
|
||||
* @param app
|
||||
* @protected
|
||||
*/
|
||||
protected static addGetResizedPhoto(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Photos.join('|') +
|
||||
'))/:size',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ThumbnailGeneratorMWs.generateThumbnailFactory(ThumbnailSourceType.Photo),
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetVideoThumbnail(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Videos.join('|') +
|
||||
'))/:size?',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ThumbnailGeneratorMWs.generateThumbnailFactory(ThumbnailSourceType.Video),
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetVideoIcon(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Videos.join('|') +
|
||||
'))/icon',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ThumbnailGeneratorMWs.generateIconFactory(ThumbnailSourceType.Video),
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetImageIcon(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Photos.join('|') +
|
||||
'))/icon',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ThumbnailGeneratorMWs.generateIconFactory(ThumbnailSourceType.Photo),
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addSearch(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/search/:searchQueryDTO(*)',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
GalleryMWs.search,
|
||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||
GalleryMWs.cleanUpGalleryResults,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
}
|
||||
|
||||
protected static addAutoComplete(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/autocomplete/:text(*)',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
GalleryMWs.autocomplete,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
}
|
||||
}
|
||||
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
|
||||
import {Express} from 'express';
|
||||
import {GalleryMWs} from '../middlewares/GalleryMWs';
|
||||
import {RenderingMWs} from '../middlewares/RenderingMWs';
|
||||
import {ThumbnailGeneratorMWs} from '../middlewares/thumbnail/ThumbnailGeneratorMWs';
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
import {ThumbnailSourceType} from '../model/fileaccess/PhotoWorker';
|
||||
import {VersionMWs} from '../middlewares/VersionMWs';
|
||||
import {SupportedFormats} from '../../common/SupportedFormats';
|
||||
import {ServerTimingMWs} from '../middlewares/ServerTimingMWs';
|
||||
import {MetaFileMWs} from '../middlewares/MetaFileMWs';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
|
||||
export class GalleryRouter {
|
||||
public static route(app: Express): void {
|
||||
this.addGetImageIcon(app);
|
||||
this.addGetVideoIcon(app);
|
||||
this.addGetResizedPhoto(app);
|
||||
this.addGetBestFitVideo(app);
|
||||
this.addGetVideoThumbnail(app);
|
||||
this.addGetImage(app);
|
||||
this.addGetVideo(app);
|
||||
this.addGetMetaFile(app);
|
||||
this.addGetBestFitMetaFile(app);
|
||||
this.addRandom(app);
|
||||
this.addDirectoryList(app);
|
||||
this.addDirectoryZip(app);
|
||||
|
||||
this.addSearch(app);
|
||||
this.addAutoComplete(app);
|
||||
}
|
||||
|
||||
protected static addDirectoryList(app: Express): void {
|
||||
app.get(
|
||||
[Config.Server.apiPath + '/gallery/content/:directory(*)', Config.Server.apiPath + '/gallery/', Config.Server.apiPath + '/gallery//'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('directory'),
|
||||
AuthenticationMWs.authorisePath('directory', true),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
GalleryMWs.listDirectory,
|
||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||
GalleryMWs.cleanUpGalleryResults,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
}
|
||||
|
||||
protected static addDirectoryZip(app: Express): void {
|
||||
app.get(
|
||||
[Config.Server.apiPath + '/gallery/zip/:directory(*)'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('directory'),
|
||||
AuthenticationMWs.authorisePath('directory', true),
|
||||
|
||||
// specific part
|
||||
ServerTimingMWs.addServerTiming,
|
||||
GalleryMWs.zipDirectory
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetImage(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Photos.join('|') +
|
||||
'))',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetVideo(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Videos.join('|') +
|
||||
'))',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetBestFitVideo(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Videos.join('|') +
|
||||
'))/bestFit',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
GalleryMWs.loadBestFitVideo,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetMetaFile(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.MetaFiles.join('|') +
|
||||
'))',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetBestFitMetaFile(app: Express): void {
|
||||
app.get(
|
||||
[
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.MetaFiles.join('|') +
|
||||
'))/bestFit',
|
||||
],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
MetaFileMWs.compressGPX,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addRandom(app: Express): void {
|
||||
app.get(
|
||||
[Config.Server.apiPath + '/gallery/random/:searchQueryDTO'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
GalleryMWs.getRandomImage,
|
||||
GalleryMWs.loadFile,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for serving photo thumbnails and previews
|
||||
* @param app
|
||||
* @protected
|
||||
*/
|
||||
protected static addGetResizedPhoto(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Photos.join('|') +
|
||||
'))/:size',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ThumbnailGeneratorMWs.generateThumbnailFactory(ThumbnailSourceType.Photo),
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetVideoThumbnail(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Videos.join('|') +
|
||||
'))/:size?',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ThumbnailGeneratorMWs.generateThumbnailFactory(ThumbnailSourceType.Video),
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetVideoIcon(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Videos.join('|') +
|
||||
'))/icon',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ThumbnailGeneratorMWs.generateIconFactory(ThumbnailSourceType.Video),
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetImageIcon(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/gallery/content/:mediaPath(*.(' +
|
||||
SupportedFormats.Photos.join('|') +
|
||||
'))/icon',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('mediaPath'),
|
||||
AuthenticationMWs.authorisePath('mediaPath', false),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.loadFile,
|
||||
ThumbnailGeneratorMWs.generateIconFactory(ThumbnailSourceType.Photo),
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
}
|
||||
|
||||
protected static addSearch(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/search/:searchQueryDTO(*)',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
GalleryMWs.search,
|
||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||
GalleryMWs.cleanUpGalleryResults,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
}
|
||||
|
||||
protected static addAutoComplete(app: Express): void {
|
||||
app.get(
|
||||
Config.Server.apiPath + '/autocomplete/:text(*)',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
GalleryMWs.autocomplete,
|
||||
ServerTimingMWs.addServerTiming,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +110,20 @@ export class Utils {
|
||||
return d;
|
||||
}
|
||||
|
||||
static getUTCFullYear(d: number | Date, offset: string) {
|
||||
if (!(d instanceof Date)) {
|
||||
d = new Date(d);
|
||||
}
|
||||
return new Date(new Date(d).toISOString().substring(0,19) + (offset ? offset : '')).getUTCFullYear();
|
||||
}
|
||||
|
||||
static getFullYear(d: number | Date, offset: string) {
|
||||
if (!(d instanceof Date)) {
|
||||
d = new Date(d);
|
||||
}
|
||||
return new Date(new Date(d).toISOString().substring(0,19) + (offset ? offset : '')).getFullYear();
|
||||
}
|
||||
|
||||
static renderDataSize(size: number): string {
|
||||
const postFixes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
let index = 0;
|
||||
|
@ -24,7 +24,8 @@
|
||||
{{media.metadata.fileSize | fileSize}}
|
||||
</div>
|
||||
<div class="col-3 align-self-center" [title]="media.metadata.creationDate">
|
||||
{{media.metadata.creationDate | date}}, {{media.metadata.creationDate | date:'mediumTime'}}
|
||||
{{ media.metadata.creationDate | date : 'longDate' : (media.metadata.creationDateOffset ? media.metadata.creationDateOffset : 'UTC') }},
|
||||
{{ media.metadata.creationDate | date : (media.metadata.creationDateOffset ? 'HH:mm:ss ZZZZZ' : 'HH:mm:ss') : (media.metadata.creationDateOffset ? media.metadata.creationDateOffset : 'UTC') }}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -205,7 +205,7 @@ export class FilterService {
|
||||
const startMediaDate = new Date(floorDate(minDate));
|
||||
|
||||
prefiltered.media.forEach(m => {
|
||||
const key = Math.floor((floorDate(m.metadata.creationDate) - startMediaDate.getTime()) / 1000 / usedDiv);
|
||||
const key = Math.floor((floorDate(m.metadata.creationDate) - startMediaDate.getTime()) / 1000 / usedDiv); //TODO
|
||||
|
||||
const getDate = (index: number) => {
|
||||
let d: Date;
|
||||
|
@ -496,7 +496,7 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
||||
case LightBoxTitleTexts.persons:
|
||||
return m.metadata.faces?.map(f => f.name)?.join(', ');
|
||||
case LightBoxTitleTexts.date:
|
||||
return this.datePipe.transform(m.metadata.creationDate, 'longDate');
|
||||
return this.datePipe.transform(m.metadata.creationDate, 'longDate', m.metadata.creationDateOffset);
|
||||
case LightBoxTitleTexts.location:
|
||||
return (
|
||||
m.metadata.positionData?.city ||
|
||||
|
@ -54,10 +54,10 @@
|
||||
</div>
|
||||
<div class="col-11">
|
||||
<div class="details-main">
|
||||
{{ media.metadata.creationDate | date: (isThisYear() ? 'MMMM d' : 'longDate') : 'UTC' }}
|
||||
{{ media.metadata.creationDate | date: (isThisYear() ? 'MMMM d' : 'longDate') : (media.metadata.creationDateOffset ? media.metadata.creationDateOffset : 'UTC') }}
|
||||
</div>
|
||||
<div class="details-sub text-secondary row">
|
||||
<div class="col-12">{{ media.metadata.creationDate | date : 'EEEE, HH:mm:ss' : 'UTC' }}</div>
|
||||
<div class="col-12">{{ media.metadata.creationDate | date : (media.metadata.creationDateOffset ? 'EEEE, HH:mm:ss ZZZZZ' : 'EEEE, HH:mm:ss') : (media.metadata.creationDateOffset ? media.metadata.creationDateOffset : 'UTC') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -148,7 +148,7 @@ export class InfoPanelLightboxComponent implements OnInit, OnChanges {
|
||||
isThisYear(): boolean {
|
||||
return (
|
||||
new Date().getFullYear() ===
|
||||
new Date(this.media.metadata.creationDate).getUTCFullYear()
|
||||
Utils.getUTCFullYear(this.media.metadata.creationDate, this.media.metadata.creationDateOffset)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ export class GallerySortingService {
|
||||
private getGroupByNameFn(grouping: GroupingMethod) {
|
||||
switch (grouping.method) {
|
||||
case SortByTypes.Date:
|
||||
return (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate', 'UTC');
|
||||
return (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate', m.metadata.creationDateOffset);
|
||||
|
||||
case SortByTypes.Name:
|
||||
return (m: MediaDTO) => m.name.at(0).toUpperCase();
|
||||
|