mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-02-15 14:03:35 +02:00
improving video support
This commit is contained in:
parent
4a7e91ceb3
commit
ad7225c62e
@ -5,7 +5,7 @@ import {Logger} from '../Logger';
|
|||||||
import {SQLConnection} from '../model/sql/SQLConnection';
|
import {SQLConnection} from '../model/sql/SQLConnection';
|
||||||
import {DataBaseConfig, DatabaseType, IndexingConfig, IPrivateConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig';
|
import {DataBaseConfig, DatabaseType, IndexingConfig, IPrivateConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig';
|
||||||
import {Config} from '../../common/config/private/Config';
|
import {Config} from '../../common/config/private/Config';
|
||||||
import {ConfigDiagnostics} from '../model/ConfigDiagnostics';
|
import {ConfigDiagnostics} from '../model/diagnostics/ConfigDiagnostics';
|
||||||
import {ClientConfig} from '../../common/config/public/ConfigClass';
|
import {ClientConfig} from '../../common/config/public/ConfigClass';
|
||||||
import {BasicConfigDTO} from '../../common/entities/settings/BasicConfigDTO';
|
import {BasicConfigDTO} from '../../common/entities/settings/BasicConfigDTO';
|
||||||
import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO';
|
import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO';
|
||||||
@ -80,6 +80,27 @@ export class AdminMWs {
|
|||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static async updateVideoSettings(req: Request, res: Response, next: NextFunction) {
|
||||||
|
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||||
|
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ConfigDiagnostics.testVideoConfig(<ClientConfig.VideoConfig>req.body.settings);
|
||||||
|
|
||||||
|
Config.Client.Video = <ClientConfig.VideoConfig>req.body.settings;
|
||||||
|
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||||
|
const original = Config.original();
|
||||||
|
original.Client.Video = <ClientConfig.VideoConfig>req.body.settings;
|
||||||
|
original.save();
|
||||||
|
await ConfigDiagnostics.runDiagnostics();
|
||||||
|
Logger.info(LOG_TAG, 'new config:');
|
||||||
|
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||||
|
return next();
|
||||||
|
} catch (err) {
|
||||||
|
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + err.toString(), err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static async updateShareSettings(req: Request, res: Response, next: NextFunction) {
|
public static async updateShareSettings(req: Request, res: Response, next: NextFunction) {
|
||||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||||
|
@ -52,7 +52,7 @@ export class GalleryMWs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static removeCyclicDirectoryReferences(req: Request, res: Response, next: NextFunction) {
|
public static cleanUpGalleryResults(req: Request, res: Response, next: NextFunction) {
|
||||||
if (!req.resultPipe) {
|
if (!req.resultPipe) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
@ -61,17 +61,6 @@ export class GalleryMWs {
|
|||||||
if (cw.notModified === true) {
|
if (cw.notModified === true) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
const removeDirs = (dir: DirectoryDTO) => {
|
|
||||||
dir.media.forEach((photo: PhotoDTO) => {
|
|
||||||
photo.directory = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
dir.directories.forEach((directory: DirectoryDTO) => {
|
|
||||||
removeDirs(directory);
|
|
||||||
directory.parent = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const cleanUpMedia = (media: MediaDTO[]) => {
|
const cleanUpMedia = (media: MediaDTO[]) => {
|
||||||
media.forEach(m => {
|
media.forEach(m => {
|
||||||
@ -89,7 +78,7 @@ export class GalleryMWs {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (cw.directory) {
|
if (cw.directory) {
|
||||||
removeDirs(cw.directory);
|
DirectoryDTO.removeReferences(cw.directory);
|
||||||
// TODO: remove when typeorm inheritance is fixed
|
// TODO: remove when typeorm inheritance is fixed
|
||||||
cleanUpMedia(cw.directory.media);
|
cleanUpMedia(cw.directory.media);
|
||||||
}
|
}
|
||||||
@ -98,6 +87,19 @@ export class GalleryMWs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Config.Client.Video.enabled === false) {
|
||||||
|
if (cw.directory) {
|
||||||
|
const removeVideos = (dir: DirectoryDTO) => {
|
||||||
|
dir.media = dir.media.filter(m => !MediaDTO.isVideo(m));
|
||||||
|
dir.directories.forEach(d => removeVideos(d));
|
||||||
|
};
|
||||||
|
removeVideos(cw.directory);
|
||||||
|
}
|
||||||
|
if (cw.searchResult) {
|
||||||
|
cw.searchResult.media = cw.searchResult.media.filter(m => !MediaDTO.isVideo(m));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
backend/model/FFmpegFactory.ts
Normal file
13
backend/model/FFmpegFactory.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export class FFmpegFactory {
|
||||||
|
public static get() {
|
||||||
|
const ffmpeg = require('fluent-ffmpeg');
|
||||||
|
try {
|
||||||
|
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
|
||||||
|
ffmpeg.setFfmpegPath(ffmpegPath);
|
||||||
|
const ffprobePath = require('@ffprobe-installer/ffprobe').path;
|
||||||
|
ffmpeg.setFfprobePath(ffprobePath);
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
return ffmpeg;
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,19 @@
|
|||||||
import {Config} from '../../common/config/private/Config';
|
import {Config} from '../../../common/config/private/Config';
|
||||||
import {
|
import {
|
||||||
DataBaseConfig,
|
DataBaseConfig,
|
||||||
DatabaseType,
|
DatabaseType,
|
||||||
IPrivateConfig,
|
IPrivateConfig,
|
||||||
ThumbnailConfig,
|
ThumbnailConfig,
|
||||||
ThumbnailProcessingLib
|
ThumbnailProcessingLib
|
||||||
} from '../../common/config/private/IPrivateConfig';
|
} from '../../../common/config/private/IPrivateConfig';
|
||||||
import {Logger} from '../Logger';
|
import {Logger} from '../../Logger';
|
||||||
import {NotificationManager} from './NotifocationManager';
|
import {NotificationManager} from '../NotifocationManager';
|
||||||
import {ProjectPath} from '../ProjectPath';
|
import {ProjectPath} from '../../ProjectPath';
|
||||||
import {SQLConnection} from './sql/SQLConnection';
|
import {SQLConnection} from '../sql/SQLConnection';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import {ClientConfig} from '../../common/config/public/ConfigClass';
|
import {ClientConfig} from '../../../common/config/public/ConfigClass';
|
||||||
|
import VideoConfig = ClientConfig.VideoConfig;
|
||||||
|
import {FFmpegFactory} from '../FFmpegFactory';
|
||||||
|
|
||||||
const LOG_TAG = '[ConfigDiagnostics]';
|
const LOG_TAG = '[ConfigDiagnostics]';
|
||||||
|
|
||||||
@ -24,6 +26,31 @@ export class ConfigDiagnostics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static testVideoConfig(videoConfig: VideoConfig) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
if (videoConfig.enabled === true) {
|
||||||
|
const ffmpeg = FFmpegFactory.get();
|
||||||
|
ffmpeg().getAvailableCodecs((err) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(new Error('Error accessing ffmpeg, cant find executable: ' + err.toString()));
|
||||||
|
}
|
||||||
|
ffmpeg(__dirname + '/blank.jpg').ffprobe((err2) => {
|
||||||
|
if (err2) {
|
||||||
|
return reject(new Error('Error accessing ffmpeg-probe, cant find executable: ' + err2.toString()));
|
||||||
|
}
|
||||||
|
return resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return resolve();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return reject(new Error('unkown video error: ' + e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static async testThumbnailLib(processingLibrary: ThumbnailProcessingLib) {
|
static async testThumbnailLib(processingLibrary: ThumbnailProcessingLib) {
|
||||||
switch (processingLibrary) {
|
switch (processingLibrary) {
|
||||||
case ThumbnailProcessingLib.sharp:
|
case ThumbnailProcessingLib.sharp:
|
||||||
@ -44,8 +71,8 @@ export class ConfigDiagnostics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async testThumbnailFolder(folder: string) {
|
static testThumbnailFolder(folder: string) {
|
||||||
await new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.access(folder, fs.constants.W_OK, (err) => {
|
fs.access(folder, fs.constants.W_OK, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject({message: 'Error during getting write access to temp folder', error: err.toString()});
|
reject({message: 'Error during getting write access to temp folder', error: err.toString()});
|
||||||
@ -55,8 +82,8 @@ export class ConfigDiagnostics {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async testImageFolder(folder: string) {
|
static testImageFolder(folder: string) {
|
||||||
await new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!fs.existsSync(folder)) {
|
if (!fs.existsSync(folder)) {
|
||||||
reject('Images folder not exists: \'' + folder + '\'');
|
reject('Images folder not exists: \'' + folder + '\'');
|
||||||
}
|
}
|
||||||
@ -164,6 +191,16 @@ export class ConfigDiagnostics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ConfigDiagnostics.testVideoConfig(Config.Client.Video);
|
||||||
|
} catch (ex) {
|
||||||
|
const err: Error = ex;
|
||||||
|
NotificationManager.warning('Video support error, switching off..', err.toString());
|
||||||
|
Logger.warn(LOG_TAG, 'Video support error, switching off..', err.toString());
|
||||||
|
Config.Client.Video.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ConfigDiagnostics.testImageFolder(Config.Server.imagesFolder);
|
await ConfigDiagnostics.testImageFolder(Config.Server.imagesFolder);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
BIN
backend/model/diagnostics/blank.jpg
Normal file
BIN
backend/model/diagnostics/blank.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 631 B |
@ -17,7 +17,7 @@ import {VideoEntity} from './enitites/VideoEntity';
|
|||||||
|
|
||||||
export class SQLConnection {
|
export class SQLConnection {
|
||||||
|
|
||||||
private static VERSION = 1;
|
private static VERSION = 2;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,17 @@ import {CameraMetadata, GPSMetadata, PhotoDTO, PhotoMetadata} from '../../../com
|
|||||||
import {Logger} from '../../Logger';
|
import {Logger} from '../../Logger';
|
||||||
import {IptcParser} from 'ts-node-iptc';
|
import {IptcParser} from 'ts-node-iptc';
|
||||||
import {ExifParserFactory, OrientationTypes} from 'ts-exif-parser';
|
import {ExifParserFactory, OrientationTypes} from 'ts-exif-parser';
|
||||||
import * as ffmpeg from 'fluent-ffmpeg';
|
|
||||||
import {FfprobeData} from 'fluent-ffmpeg';
|
import {FfprobeData} from 'fluent-ffmpeg';
|
||||||
import {ProjectPath} from '../../ProjectPath';
|
import {ProjectPath} from '../../ProjectPath';
|
||||||
import {Config} from '../../../common/config/private/Config';
|
import {Config} from '../../../common/config/private/Config';
|
||||||
import {VideoDTO, VideoMetadata} from '../../../common/entities/VideoDTO';
|
import {VideoDTO, VideoMetadata} from '../../../common/entities/VideoDTO';
|
||||||
import {MediaDimension, MediaMetadata} from '../../../common/entities/MediaDTO';
|
import {MediaDimension} from '../../../common/entities/MediaDTO';
|
||||||
|
import {FFmpegFactory} from '../FFmpegFactory';
|
||||||
|
|
||||||
const LOG_TAG = '[DiskManagerTask]';
|
const LOG_TAG = '[DiskManagerTask]';
|
||||||
|
|
||||||
|
const ffmpeg = FFmpegFactory.get();
|
||||||
|
|
||||||
export class DiskMangerWorker {
|
export class DiskMangerWorker {
|
||||||
private static isImage(fullPath: string) {
|
private static isImage(fullPath: string) {
|
||||||
const extensions = [
|
const extensions = [
|
||||||
@ -33,8 +35,7 @@ export class DiskMangerWorker {
|
|||||||
|
|
||||||
private static isVideo(fullPath: string) {
|
private static isVideo(fullPath: string) {
|
||||||
const extensions = [
|
const extensions = [
|
||||||
'.mp4',
|
'.mp4'
|
||||||
'.webm'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const extension = path.extname(fullPath).toLowerCase();
|
const extension = path.extname(fullPath).toLowerCase();
|
||||||
@ -83,7 +84,8 @@ export class DiskMangerWorker {
|
|||||||
if (maxPhotos != null && directory.media.length > maxPhotos) {
|
if (maxPhotos != null && directory.media.length > maxPhotos) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (DiskMangerWorker.isVideo(fullFilePath)) {
|
} else if (Config.Client.Video.enabled === true &&
|
||||||
|
DiskMangerWorker.isVideo(fullFilePath)) {
|
||||||
directory.media.push(<VideoDTO>{
|
directory.media.push(<VideoDTO>{
|
||||||
name: file,
|
name: file,
|
||||||
directory: null,
|
directory: null,
|
||||||
@ -98,7 +100,7 @@ export class DiskMangerWorker {
|
|||||||
|
|
||||||
return resolve(directory);
|
return resolve(directory);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return reject({error: err});
|
return reject({error: err.toString()});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ import {Dimensions, State} from 'gm';
|
|||||||
import {Logger} from '../../Logger';
|
import {Logger} from '../../Logger';
|
||||||
import {FfmpegCommand, FfprobeData} from 'fluent-ffmpeg';
|
import {FfmpegCommand, FfprobeData} from 'fluent-ffmpeg';
|
||||||
import {ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig';
|
import {ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig';
|
||||||
|
import {FFmpegFactory} from '../FFmpegFactory';
|
||||||
|
|
||||||
export class ThumbnailWorker {
|
export class ThumbnailWorker {
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ export interface RendererInput {
|
|||||||
|
|
||||||
export class VideoRendererFactory {
|
export class VideoRendererFactory {
|
||||||
public static build(): (input: RendererInput) => Promise<void> {
|
public static build(): (input: RendererInput) => Promise<void> {
|
||||||
const ffmpeg = require('fluent-ffmpeg');
|
const ffmpeg = FFmpegFactory.get();
|
||||||
return (input: RendererInput): Promise<void> => {
|
return (input: RendererInput): Promise<void> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
@ -59,6 +59,12 @@ export class AdminRouter {
|
|||||||
AdminMWs.updateMapSettings,
|
AdminMWs.updateMapSettings,
|
||||||
RenderingMWs.renderOK
|
RenderingMWs.renderOK
|
||||||
);
|
);
|
||||||
|
app.put('/api/settings/video',
|
||||||
|
AuthenticationMWs.authenticate,
|
||||||
|
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||||
|
AdminMWs.updateVideoSettings,
|
||||||
|
RenderingMWs.renderOK
|
||||||
|
);
|
||||||
|
|
||||||
app.put('/api/settings/authentication',
|
app.put('/api/settings/authentication',
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
@ -27,7 +27,7 @@ export class GalleryRouter {
|
|||||||
AuthenticationMWs.authoriseDirectory,
|
AuthenticationMWs.authoriseDirectory,
|
||||||
GalleryMWs.listDirectory,
|
GalleryMWs.listDirectory,
|
||||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||||
GalleryMWs.removeCyclicDirectoryReferences,
|
GalleryMWs.cleanUpGalleryResults,
|
||||||
RenderingMWs.renderResult
|
RenderingMWs.renderResult
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ export class GalleryRouter {
|
|||||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||||
GalleryMWs.search,
|
GalleryMWs.search,
|
||||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||||
GalleryMWs.removeCyclicDirectoryReferences,
|
GalleryMWs.cleanUpGalleryResults,
|
||||||
RenderingMWs.renderResult
|
RenderingMWs.renderResult
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ export class GalleryRouter {
|
|||||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||||
GalleryMWs.instantSearch,
|
GalleryMWs.instantSearch,
|
||||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||||
GalleryMWs.removeCyclicDirectoryReferences,
|
GalleryMWs.cleanUpGalleryResults,
|
||||||
RenderingMWs.renderResult
|
RenderingMWs.renderResult
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import {LoggerRouter} from './routes/LoggerRouter';
|
|||||||
import {ThumbnailGeneratorMWs} from './middlewares/thumbnail/ThumbnailGeneratorMWs';
|
import {ThumbnailGeneratorMWs} from './middlewares/thumbnail/ThumbnailGeneratorMWs';
|
||||||
import {DiskManager} from './model/DiskManger';
|
import {DiskManager} from './model/DiskManger';
|
||||||
import {NotificationRouter} from './routes/NotificationRouter';
|
import {NotificationRouter} from './routes/NotificationRouter';
|
||||||
import {ConfigDiagnostics} from './model/ConfigDiagnostics';
|
import {ConfigDiagnostics} from './model/diagnostics/ConfigDiagnostics';
|
||||||
import {Localizations} from './model/Localizations';
|
import {Localizations} from './model/Localizations';
|
||||||
import {CookieNames} from '../common/CookieNames';
|
import {CookieNames} from '../common/CookieNames';
|
||||||
|
|
||||||
|
@ -43,6 +43,11 @@ export module ClientConfig {
|
|||||||
NavBar: NavBarConfig;
|
NavBar: NavBarConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface VideoConfig {
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
applicationTitle: string;
|
applicationTitle: string;
|
||||||
publicUrl: string;
|
publicUrl: string;
|
||||||
@ -55,6 +60,7 @@ export module ClientConfig {
|
|||||||
Other: OtherConfig;
|
Other: OtherConfig;
|
||||||
authenticationRequired: boolean;
|
authenticationRequired: boolean;
|
||||||
languages: string[];
|
languages: string[];
|
||||||
|
Video: VideoConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -91,6 +97,9 @@ export class PublicConfigClass {
|
|||||||
RandomPhoto: {
|
RandomPhoto: {
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
|
Video: {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
Other: {
|
Other: {
|
||||||
enableCache: true,
|
enableCache: true,
|
||||||
enableOnScrollRendering: true,
|
enableOnScrollRendering: true,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {MediaDTO} from './MediaDTO';
|
import {MediaDTO} from './MediaDTO';
|
||||||
|
import {PhotoDTO} from './PhotoDTO';
|
||||||
|
|
||||||
export interface DirectoryDTO {
|
export interface DirectoryDTO {
|
||||||
id: number;
|
id: number;
|
||||||
@ -23,4 +24,16 @@ export module DirectoryDTO {
|
|||||||
directory.parent = dir;
|
directory.parent = dir;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const removeReferences = (dir: DirectoryDTO) => {
|
||||||
|
dir.media.forEach((photo: PhotoDTO) => {
|
||||||
|
photo.directory = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
dir.directories.forEach((directory: DirectoryDTO) => {
|
||||||
|
removeReferences(directory);
|
||||||
|
directory.parent = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -43,13 +43,15 @@
|
|||||||
<app-settings-database [simplifiedMode]="simplifiedMode"></app-settings-database>
|
<app-settings-database [simplifiedMode]="simplifiedMode"></app-settings-database>
|
||||||
<app-settings-thumbnail #thumbnail [hidden]="!thumbnail.hasAvailableSettings"
|
<app-settings-thumbnail #thumbnail [hidden]="!thumbnail.hasAvailableSettings"
|
||||||
[simplifiedMode]="simplifiedMode"></app-settings-thumbnail>
|
[simplifiedMode]="simplifiedMode"></app-settings-thumbnail>
|
||||||
|
<app-settings-video #video [hidden]="!video.hasAvailableSettings"
|
||||||
|
[simplifiedMode]="simplifiedMode"></app-settings-video>
|
||||||
<app-settings-search #search [hidden]="!search.hasAvailableSettings"
|
<app-settings-search #search [hidden]="!search.hasAvailableSettings"
|
||||||
[simplifiedMode]="simplifiedMode"></app-settings-search>
|
[simplifiedMode]="simplifiedMode"></app-settings-search>
|
||||||
<app-settings-share #share [hidden]="!share.hasAvailableSettings"
|
<app-settings-share #share [hidden]="!share.hasAvailableSettings"
|
||||||
[simplifiedMode]="simplifiedMode"></app-settings-share>
|
[simplifiedMode]="simplifiedMode"></app-settings-share>
|
||||||
<app-settings-map #map [hidden]="!map.hasAvailableSettings" [simplifiedMode]="simplifiedMode"></app-settings-map>
|
<app-settings-map #map [hidden]="!map.hasAvailableSettings" [simplifiedMode]="simplifiedMode"></app-settings-map>
|
||||||
<app-settings-random-photo #random [hidden]="!random.hasAvailableSettings"
|
<app-settings-random-photo #random [hidden]="!random.hasAvailableSettings"
|
||||||
[simplifiedMode]="simplifiedMode"></app-settings-random-photo>
|
[simplifiedMode]="simplifiedMode"></app-settings-random-photo>
|
||||||
<app-settings-other #other [hidden]="!other.hasAvailableSettings"
|
<app-settings-other #other [hidden]="!other.hasAvailableSettings"
|
||||||
[simplifiedMode]="simplifiedMode"></app-settings-other>
|
[simplifiedMode]="simplifiedMode"></app-settings-other>
|
||||||
<app-settings-indexing #indexing [hidden]="!indexing.hasAvailableSettings"
|
<app-settings-indexing #indexing [hidden]="!indexing.hasAvailableSettings"
|
||||||
|
@ -73,6 +73,7 @@ import {StringifySortingMethod} from './pipes/StringifySortingMethod';
|
|||||||
import {RandomQueryBuilderGalleryComponent} from './gallery/random-query-builder/random-query-builder.gallery.component';
|
import {RandomQueryBuilderGalleryComponent} from './gallery/random-query-builder/random-query-builder.gallery.component';
|
||||||
import {RandomPhotoSettingsComponent} from './settings/random-photo/random-photo.settings.component';
|
import {RandomPhotoSettingsComponent} from './settings/random-photo/random-photo.settings.component';
|
||||||
import {FixOrientationPipe} from './gallery/FixOrientationPipe';
|
import {FixOrientationPipe} from './gallery/FixOrientationPipe';
|
||||||
|
import {VideoSettingsComponent} from './settings/video/video.settings.component';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GoogleMapsConfig {
|
export class GoogleMapsConfig {
|
||||||
@ -159,6 +160,7 @@ export function translationsFactory(locale: string) {
|
|||||||
DatabaseSettingsComponent,
|
DatabaseSettingsComponent,
|
||||||
MapSettingsComponent,
|
MapSettingsComponent,
|
||||||
ThumbnailSettingsComponent,
|
ThumbnailSettingsComponent,
|
||||||
|
VideoSettingsComponent,
|
||||||
SearchSettingsComponent,
|
SearchSettingsComponent,
|
||||||
ShareSettingsComponent,
|
ShareSettingsComponent,
|
||||||
RandomPhotoSettingsComponent,
|
RandomPhotoSettingsComponent,
|
||||||
|
@ -135,7 +135,7 @@ export abstract class SettingsComponent<T, S extends AbstractSettingsService<T>
|
|||||||
try {
|
try {
|
||||||
await this._settingsService.updateSettings(this.settings);
|
await this._settingsService.updateSettings(this.settings);
|
||||||
await this.getSettings();
|
await this.getSettings();
|
||||||
this.notification.success(this.name + this.i18n(' settings saved'), this.i18n('Success'));
|
this.notification.success(this.name + ' ' + this.i18n('settings saved'), this.i18n('Success'));
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
<ng-container *ngIf="settings.type == DatabaseType.mysql">
|
<ng-container *ngIf="settings.type == DatabaseType.mysql">
|
||||||
<p class="title" i18n>MySQL settings:</p>
|
<p class="title" i18n>MySQL settings:</p>
|
||||||
<input type="text" class="form-control" i18n-placeholder placeholder="Host" autofocus
|
<input type="text" class="form-control" i18n-placeholder placeholder="Host"
|
||||||
[(ngModel)]="settings.mysql.host" name="host" required>
|
[(ngModel)]="settings.mysql.host" name="host" required>
|
||||||
<input type="text" class="form-control" i18n-placeholder placeholder="Database" autofocus
|
<input type="text" class="form-control" i18n-placeholder placeholder="Database"
|
||||||
[(ngModel)]="settings.mysql.database" name="database" required>
|
[(ngModel)]="settings.mysql.database" name="database" required>
|
||||||
<input type="text" class="form-control" i18n-placeholder placeholder="Username"
|
<input type="text" class="form-control" i18n-placeholder placeholder="Username"
|
||||||
[(ngModel)]="settings.mysql.username" name="username">
|
[(ngModel)]="settings.mysql.username" name="username">
|
||||||
|
@ -36,6 +36,9 @@ export class SettingsService {
|
|||||||
RandomPhoto: {
|
RandomPhoto: {
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
|
Video: {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
Other: {
|
Other: {
|
||||||
enableCache: true,
|
enableCache: true,
|
||||||
enableOnScrollRendering: true,
|
enableOnScrollRendering: true,
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<form #NewUserForm="ngForm">
|
<form #NewUserForm="ngForm">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<input type="text" class="form-control" i18n-placeholder placeholder="Username" autofocus
|
<input type="text" class="form-control" i18n-placeholder placeholder="Username"
|
||||||
[(ngModel)]="newUser.name" name="name" required>
|
[(ngModel)]="newUser.name" name="name" required>
|
||||||
<input type="password" class="form-control" i18n-placeholder placeholder="Password"
|
<input type="password" class="form-control" i18n-placeholder placeholder="Password"
|
||||||
[(ngModel)]="newUser.password" name="password" required>
|
[(ngModel)]="newUser.password" name="password" required>
|
||||||
|
36
frontend/app/settings/video/video.settings.component.html
Normal file
36
frontend/app/settings/video/video.settings.component.html
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<form #settingsForm="ngForm" class="form-horizontal">
|
||||||
|
<div class="card mb-4">
|
||||||
|
<h5 class="card-header">
|
||||||
|
<ng-container i18n>Video settings</ng-container>
|
||||||
|
<div class="switch-wrapper">
|
||||||
|
<bSwitch
|
||||||
|
class="switch"
|
||||||
|
name="enabled"
|
||||||
|
[switch-on-color]="'success'"
|
||||||
|
[switch-inverse]="'inverse'"
|
||||||
|
[switch-off-text]="text.Disabled"
|
||||||
|
[switch-on-text]="text.Enabled"
|
||||||
|
[switch-disabled]="inProgress"
|
||||||
|
[switch-handle-width]="'100'"
|
||||||
|
[switch-label-width]="'20'"
|
||||||
|
[(ngModel)]="settings.enabled">
|
||||||
|
</bSwitch>
|
||||||
|
</div>
|
||||||
|
</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||||
|
|
||||||
|
<ng-container i18n>Video support uses ffmpeg. ffmpeg and ffprobe binaries need to be available in the PATH or the @ffmpeg-installer/ffmpeg and @ffprobe-installer/ffprobe optional node packages need to be installed.</ng-container>
|
||||||
|
|
||||||
|
|
||||||
|
<button class="btn btn-success float-right"
|
||||||
|
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||||
|
(click)="save()" i18n>Save
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-default float-right"
|
||||||
|
(click)="reset()" i18n>Reset
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
32
frontend/app/settings/video/video.settings.component.ts
Normal file
32
frontend/app/settings/video/video.settings.component.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import {Component} from '@angular/core';
|
||||||
|
import {VideoSettingsService} from './video.settings.service';
|
||||||
|
import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||||
|
import {AuthenticationService} from '../../model/network/authentication.service';
|
||||||
|
import {NavigationService} from '../../model/navigation.service';
|
||||||
|
import {NotificationService} from '../../model/notification.service';
|
||||||
|
import {ClientConfig} from '../../../../common/config/public/ConfigClass';
|
||||||
|
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-settings-video',
|
||||||
|
templateUrl: './video.settings.component.html',
|
||||||
|
styleUrls: ['./video.settings.component.css',
|
||||||
|
'./../_abstract/abstract.settings.component.css'],
|
||||||
|
providers: [VideoSettingsService],
|
||||||
|
})
|
||||||
|
export class VideoSettingsComponent extends SettingsComponent<ClientConfig.VideoConfig> {
|
||||||
|
|
||||||
|
constructor(_authService: AuthenticationService,
|
||||||
|
_navigation: NavigationService,
|
||||||
|
_settingsService: VideoSettingsService,
|
||||||
|
notification: NotificationService,
|
||||||
|
i18n: I18n) {
|
||||||
|
super(i18n('Video'), _authService, _navigation, <any>_settingsService, notification, i18n, s => s.Client.Video);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
19
frontend/app/settings/video/video.settings.service.ts
Normal file
19
frontend/app/settings/video/video.settings.service.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {NetworkService} from '../../model/network/network.service';
|
||||||
|
import {ClientConfig} from '../../../../common/config/public/ConfigClass';
|
||||||
|
import {SettingsService} from '../settings.service';
|
||||||
|
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class VideoSettingsService extends AbstractSettingsService<ClientConfig.MapConfig> {
|
||||||
|
constructor(private _networkService: NetworkService,
|
||||||
|
_settingsService: SettingsService) {
|
||||||
|
super(_settingsService);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateSettings(settings: ClientConfig.VideoConfig): Promise<void> {
|
||||||
|
return this._networkService.putJson('/settings/video', {settings: settings});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -104,7 +104,7 @@
|
|||||||
<source>download</source>
|
<source>download</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">25</context>
|
<context context-type="linenumber">27</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>download</target>
|
<target>download</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -112,7 +112,7 @@
|
|||||||
<source>info</source>
|
<source>info</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">29</context>
|
<context context-type="linenumber">31</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>info</target>
|
<target>info</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -120,11 +120,11 @@
|
|||||||
<source>toggle fullscreen</source>
|
<source>toggle fullscreen</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">36</context>
|
<context context-type="linenumber">38</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">45</context>
|
<context context-type="linenumber">47</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>toggle fullscreen</target>
|
<target>toggle fullscreen</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -132,7 +132,7 @@
|
|||||||
<source>close</source>
|
<source>close</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">52</context>
|
<context context-type="linenumber">54</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>close</target>
|
<target>close</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -140,7 +140,7 @@
|
|||||||
<source>key: left arrow</source>
|
<source>key: left arrow</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">60</context>
|
<context context-type="linenumber">68</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>key: left arrow</target>
|
<target>key: left arrow</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -148,7 +148,7 @@
|
|||||||
<source>key: right arrow</source>
|
<source>key: right arrow</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">64</context>
|
<context context-type="linenumber">72</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>key: right arrow</target>
|
<target>key: right arrow</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -607,6 +607,10 @@
|
|||||||
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
|
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
|
||||||
<context context-type="linenumber">104</context>
|
<context context-type="linenumber">104</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">app/settings/video/video.settings.component.html</context>
|
||||||
|
<context context-type="linenumber">28</context>
|
||||||
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/settings/search/search.settings.component.html</context>
|
<context context-type="sourcefile">app/settings/search/search.settings.component.html</context>
|
||||||
<context context-type="linenumber">73</context>
|
<context context-type="linenumber">73</context>
|
||||||
@ -640,6 +644,10 @@
|
|||||||
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
|
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
|
||||||
<context context-type="linenumber">107</context>
|
<context context-type="linenumber">107</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">app/settings/video/video.settings.component.html</context>
|
||||||
|
<context context-type="linenumber">31</context>
|
||||||
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/settings/search/search.settings.component.html</context>
|
<context context-type="sourcefile">app/settings/search/search.settings.component.html</context>
|
||||||
<context context-type="linenumber">76</context>
|
<context context-type="linenumber">76</context>
|
||||||
@ -796,6 +804,22 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<target>';' separated integers. If size is 200, that thumbnail will have 200^2 pixels.</target>
|
<target>';' separated integers. If size is 200, that thumbnail will have 200^2 pixels.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="b5398623f87ee72ed23f5023918db1707771e925" datatype="html">
|
||||||
|
<source>Video settings</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">app/settings/video/video.settings.component.html</context>
|
||||||
|
<context context-type="linenumber">4</context>
|
||||||
|
</context-group>
|
||||||
|
<target>Video settings</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="6b8862cecf0fd1c8fc1b503e131bfa230d851343" datatype="html">
|
||||||
|
<source>Video support uses ffmpeg. ffmpeg and ffprobe binaries need to be available in the PATH or the @ffmpeg-installer/ffmpeg and @ffprobe-installer/ffprobe optional node packages need to be installed.</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">app/settings/video/video.settings.component.html</context>
|
||||||
|
<context context-type="linenumber">23</context>
|
||||||
|
</context-group>
|
||||||
|
<target>Video support uses ffmpeg. ffmpeg and ffprobe binaries need to be available in the PATH or the @ffmpeg-installer/ffmpeg and @ffprobe-installer/ffprobe optional node packages need to be installed.</target>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="2e75ae3885931555902da6b288ed616843d5dc3c" datatype="html">
|
<trans-unit id="2e75ae3885931555902da6b288ed616843d5dc3c" datatype="html">
|
||||||
<source>Search settings</source>
|
<source>Search settings</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
@ -1467,8 +1491,8 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<target>High</target>
|
<target>High</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="03d4d456b5f14c7bdd428393e17c724cd5210852" datatype="html">
|
<trans-unit id="04e4b67fdc5f633a81e0ab32c1751ab20e6e3034" datatype="html">
|
||||||
<source> settings saved</source>
|
<source>settings saved</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">frontend/app/settings/_abstract/abstract.settings.component.ts</context>
|
<context context-type="sourcefile">frontend/app/settings/_abstract/abstract.settings.component.ts</context>
|
||||||
<context context-type="linenumber">1</context>
|
<context context-type="linenumber">1</context>
|
||||||
@ -1591,13 +1615,13 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<target>Other</target>
|
<target>Other</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="59b428a89fc1e287f2fb60806ed5f0588cb9c270" datatype="html">
|
<trans-unit id="e636143d733fa6a21fa62ffdff2fd76c221e6cac" datatype="html">
|
||||||
<source>Random Photo</source>
|
<source>Random Media</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">frontend/app/settings/random-photo/random-photo.settings.component.ts</context>
|
<context context-type="sourcefile">frontend/app/settings/random-photo/random-photo.settings.component.ts</context>
|
||||||
<context context-type="linenumber">1</context>
|
<context context-type="linenumber">1</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>Random Photo</target>
|
<target>Random Media</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="45dda89cf029b7d7b457a8dff01dc4b9a6485816" datatype="html">
|
<trans-unit id="45dda89cf029b7d7b457a8dff01dc4b9a6485816" datatype="html">
|
||||||
<source>Thumbnail</source>
|
<source>Thumbnail</source>
|
||||||
@ -1639,6 +1663,14 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<target>Password protection disabled</target>
|
<target>Password protection disabled</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="2d1ea268a6a9f483dbc2cbfe19bf4256a57a6af4" datatype="html">
|
||||||
|
<source>Video</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">frontend/app/settings/video/video.settings.component.ts</context>
|
||||||
|
<context context-type="linenumber">1</context>
|
||||||
|
</context-group>
|
||||||
|
<target>Video</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
@ -104,7 +104,7 @@
|
|||||||
<source>download</source>
|
<source>download</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">25</context>
|
<context context-type="linenumber">27</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>letöltés</target>
|
<target>letöltés</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -112,7 +112,7 @@
|
|||||||
<source>info</source>
|
<source>info</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">29</context>
|
<context context-type="linenumber">31</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>info</target>
|
<target>info</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -120,11 +120,11 @@
|
|||||||
<source>toggle fullscreen</source>
|
<source>toggle fullscreen</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">36</context>
|
<context context-type="linenumber">38</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">45</context>
|
<context context-type="linenumber">47</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>teljes képernyőre váltás</target>
|
<target>teljes képernyőre váltás</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -132,7 +132,7 @@
|
|||||||
<source>close</source>
|
<source>close</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">52</context>
|
<context context-type="linenumber">54</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>bezárás</target>
|
<target>bezárás</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -140,7 +140,7 @@
|
|||||||
<source>key: left arrow</source>
|
<source>key: left arrow</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">60</context>
|
<context context-type="linenumber">68</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>billentyű: balra nyíl</target>
|
<target>billentyű: balra nyíl</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -148,7 +148,7 @@
|
|||||||
<source>key: right arrow</source>
|
<source>key: right arrow</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
<context context-type="sourcefile">app/gallery/lightbox/lightbox.gallery.component.html</context>
|
||||||
<context context-type="linenumber">64</context>
|
<context context-type="linenumber">72</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>billentyű: jobbra nyíl</target>
|
<target>billentyű: jobbra nyíl</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -607,6 +607,10 @@
|
|||||||
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
|
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
|
||||||
<context context-type="linenumber">104</context>
|
<context context-type="linenumber">104</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">app/settings/video/video.settings.component.html</context>
|
||||||
|
<context context-type="linenumber">28</context>
|
||||||
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/settings/search/search.settings.component.html</context>
|
<context context-type="sourcefile">app/settings/search/search.settings.component.html</context>
|
||||||
<context context-type="linenumber">73</context>
|
<context context-type="linenumber">73</context>
|
||||||
@ -640,6 +644,10 @@
|
|||||||
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
|
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
|
||||||
<context context-type="linenumber">107</context>
|
<context context-type="linenumber">107</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">app/settings/video/video.settings.component.html</context>
|
||||||
|
<context context-type="linenumber">31</context>
|
||||||
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">app/settings/search/search.settings.component.html</context>
|
<context context-type="sourcefile">app/settings/search/search.settings.component.html</context>
|
||||||
<context context-type="linenumber">76</context>
|
<context context-type="linenumber">76</context>
|
||||||
@ -796,6 +804,22 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<target>';' elválasztott egész számok. Ha a méretnek pl. 200-t állítasz be, akkor a thumbnail 200^2 pixelből fog állni.</target>
|
<target>';' elválasztott egész számok. Ha a méretnek pl. 200-t állítasz be, akkor a thumbnail 200^2 pixelből fog állni.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="b5398623f87ee72ed23f5023918db1707771e925" datatype="html">
|
||||||
|
<source>Video settings</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">app/settings/video/video.settings.component.html</context>
|
||||||
|
<context context-type="linenumber">4</context>
|
||||||
|
</context-group>
|
||||||
|
<target>Videó beállítások</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="6b8862cecf0fd1c8fc1b503e131bfa230d851343" datatype="html">
|
||||||
|
<source>Video support uses ffmpeg. ffmpeg and ffprobe binaries need to be available in the PATH or the @ffmpeg-installer/ffmpeg and @ffprobe-installer/ffprobe optional node packages need to be installed.</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">app/settings/video/video.settings.component.html</context>
|
||||||
|
<context context-type="linenumber">23</context>
|
||||||
|
</context-group>
|
||||||
|
<target>A videó lejátszához az ffmpeg szükséges. Az ffmpeg és az ffprobe binárisoknak rendelkezésre kell állniuk a PATH-ban vagy az @ffmpeg-installer/ffmpeg és @ffprobe-installer/ffprobe opcionális node csomagokat kell telepíteni.</target>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="2e75ae3885931555902da6b288ed616843d5dc3c" datatype="html">
|
<trans-unit id="2e75ae3885931555902da6b288ed616843d5dc3c" datatype="html">
|
||||||
<source>Search settings</source>
|
<source>Search settings</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
@ -1467,8 +1491,8 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<target>Magas</target>
|
<target>Magas</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="03d4d456b5f14c7bdd428393e17c724cd5210852" datatype="html">
|
<trans-unit id="04e4b67fdc5f633a81e0ab32c1751ab20e6e3034" datatype="html">
|
||||||
<source> settings saved</source>
|
<source>settings saved</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">frontend/app/settings/_abstract/abstract.settings.component.ts</context>
|
<context context-type="sourcefile">frontend/app/settings/_abstract/abstract.settings.component.ts</context>
|
||||||
<context context-type="linenumber">1</context>
|
<context context-type="linenumber">1</context>
|
||||||
@ -1591,13 +1615,13 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<target>Egyéb</target>
|
<target>Egyéb</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="59b428a89fc1e287f2fb60806ed5f0588cb9c270" datatype="html">
|
<trans-unit id="e636143d733fa6a21fa62ffdff2fd76c221e6cac" datatype="html">
|
||||||
<source>Random Photo</source>
|
<source>Random Media</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">frontend/app/settings/random-photo/random-photo.settings.component.ts</context>
|
<context context-type="sourcefile">frontend/app/settings/random-photo/random-photo.settings.component.ts</context>
|
||||||
<context context-type="linenumber">1</context>
|
<context context-type="linenumber">1</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<target>Véletlen fotó</target>
|
<target>Véletlenszerű média</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="45dda89cf029b7d7b457a8dff01dc4b9a6485816" datatype="html">
|
<trans-unit id="45dda89cf029b7d7b457a8dff01dc4b9a6485816" datatype="html">
|
||||||
<source>Thumbnail</source>
|
<source>Thumbnail</source>
|
||||||
@ -1639,6 +1663,14 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<target>Jelszavas védelem tiltva</target>
|
<target>Jelszavas védelem tiltva</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="2d1ea268a6a9f483dbc2cbfe19bf4256a57a6af4" datatype="html">
|
||||||
|
<source>Video</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">frontend/app/settings/video/video.settings.component.ts</context>
|
||||||
|
<context context-type="linenumber">1</context>
|
||||||
|
</context-group>
|
||||||
|
<target>Videó</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
@ -119,9 +119,11 @@
|
|||||||
"natives": "1.1.3"
|
"natives": "1.1.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"mysql": "2.16.0",
|
"@ffmpeg-installer/ffmpeg": "1.0.16",
|
||||||
|
"@ffprobe-installer/ffprobe": "1.0.9",
|
||||||
"bcrypt": "3.0.2",
|
"bcrypt": "3.0.2",
|
||||||
"gm": "1.23.1",
|
"gm": "1.23.1",
|
||||||
|
"mysql": "2.16.0",
|
||||||
"sharp": "0.21.0"
|
"sharp": "0.21.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user