1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-01-12 04:23:09 +02:00

implementing basic Internationalization

This commit is contained in:
Patrik J. Braun 2017-12-24 18:42:25 -05:00
parent 9d84c410cd
commit 3124b3be64
39 changed files with 1350 additions and 172 deletions

View File

@ -0,0 +1,18 @@
import {ProjectPath} from "../ProjectPath";
import * as fs from "fs";
import * as path from "path";
import {Config} from "../../common/config/private/Config";
export class Localizations {
constructor() {
}
public static init() {
const notLanguage = ['assets'];
const dirCont = fs.readdirSync(ProjectPath.FrontendFolder).filter(f => fs.statSync(path.resolve(ProjectPath.FrontendFolder, f)).isDirectory());
Config.Client.languages = dirCont.filter(d => notLanguage.indexOf(d) == -1);
Config.Client.languages.push("en");
}
}

View File

@ -1,16 +1,46 @@
import * as _express from "express";
import {NextFunction, Request, Response} from "express";
import * as _path from "path";
import * as path from "path";
import * as fs from "fs";
import {Utils} from "../../common/Utils";
import {Config} from "../../common/config/private/Config";
import {ProjectPath} from "../ProjectPath";
import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs";
import {CookieNames} from "../../common/CookieNames";
export class PublicRouter {
public static route(app) {
const setLocale = (req: Request, res: Response, next: Function) => {
let localePath = "";
let selectedLocale = req['locale'];
if (req.cookies && req.cookies[CookieNames.lang]) {
if (Config.Client.languages.indexOf(req.cookies[CookieNames.lang]) !== -1) {
console.log(selectedLocale);
selectedLocale = req.cookies[CookieNames.lang];
}
}
if (selectedLocale !== 'en') {
localePath = req['locale'];
}
res.cookie(CookieNames.lang, selectedLocale);
req['localePath'] = localePath;
next();
};
const renderIndex = (req: Request, res: Response) => {
res.sendFile(_path.resolve(ProjectPath.FrontendFolder, 'index.html'), {maxAge: 31536000});
res.sendFile(path.resolve(ProjectPath.FrontendFolder, req['localePath'], 'index.html'), {maxAge: 31536000});
};
const redirectToBase = (locale: string) => {
return (req: Request, res: Response) => {
console.log(locale);
if (Config.Client.languages.indexOf(locale) !== -1) {
res.cookie(CookieNames.lang, locale);
}
res.redirect("/");
};
};
app.use(
@ -29,16 +59,42 @@ export class PublicRouter {
});
app.get('/config_inject.js', (req: Request, res: Response) => {
res.render(_path.resolve(ProjectPath.FrontendFolder, 'config_inject.ejs'), res.tpl);
res.render(path.resolve(ProjectPath.FrontendFolder, 'config_inject.ejs'), res.tpl);
});
app.get(['/', '/login', "/gallery*", "/share*", "/admin", "/search*"],
AuthenticationMWs.tryAuthenticate,
setLocale,
renderIndex
);
Config.Client.languages.forEach(l => {
app.get(['/' + l + '/', '/' + l + '/login', '/' + l + "/gallery*", '/' + l + "/share*", '/' + l + "/admin", '/' + l + "/search*"],
redirectToBase(l)
);
});
app.use(_express.static(ProjectPath.FrontendFolder, {maxAge: 31536000}));
// app.use('/node_modules', _express.static(_path.resolve(__dirname, './../../node_modules')));
// app.use('/common', _express.static(_path.resolve(__dirname, './../../common')));
app.get('/assets/:file',
setLocale,
(req: Request, res: Response) => {
const file = path.resolve(ProjectPath.FrontendFolder, req['localePath'], 'assets', req.params.file);
fs.exists(file, (exists: boolean) => {
if (!exists) {
return res.sendStatus(404);
}
res.sendFile(file);
});
});
app.get('/:file',
setLocale,
(req: Request, res: Response) => {
const file = path.resolve(ProjectPath.FrontendFolder, req['localePath'], req.params.file);
fs.exists(file, (exists: boolean) => {
if (!exists) {
return res.sendStatus(404);
}
res.sendFile(file);
});
});
}
}

View File

@ -1,6 +1,8 @@
import * as _express from "express";
import * as _bodyParser from "body-parser";
import * as cookieParser from "cookie-parser";
import * as _http from "http";
import * as locale from "locale";
import {PublicRouter} from "./routes/PublicRouter";
import {UserRouter} from "./routes/UserRouter";
import {GalleryRouter} from "./routes/GalleryRouter";
@ -16,6 +18,8 @@ import {ThumbnailGeneratorMWs} from "./middlewares/thumbnail/ThumbnailGeneratorM
import {DiskManager} from "./model/DiskManger";
import {NotificationRouter} from "./routes/NotificationRouter";
import {ConfigDiagnostics} from "./model/ConfigDiagnostics";
import {Localizations} from "./model/Localizations";
import {CookieNames} from "../common/CookieNames";
const _session = require('cookie-session');
@ -56,7 +60,7 @@ export class Server {
}
this.app.use(_session({
name: "pigallery2-session",
name: CookieNames.session,
keys: ["key1" + s4() + s4() + s4() + s4(), "key2" + s4() + s4() + s4() + s4(), "key3" + s4() + s4() + s4() + s4()]
}));
@ -71,9 +75,13 @@ export class Server {
*/
// for parsing application/json
this.app.use(_bodyParser.json());
this.app.use(cookieParser());
DiskManager.init();
ThumbnailGeneratorMWs.init();
Localizations.init();
this.app.use(locale(Config.Client.languages, "en"));
if (Config.Server.database.type != DatabaseType.memory) {
await ObjectManagerRepository.InitSQLManagers();
} else {

4
common/CookieNames.ts Normal file
View File

@ -0,0 +1,4 @@
export class CookieNames {
public static lang = "pigallery2-lang";
public static session = "pigallery2-session";
}

View File

@ -36,6 +36,7 @@ export module ClientConfig {
enableOnScrollThumbnailPrioritising: boolean;
authenticationRequired: boolean;
publicUrl: string;
languages: string[];
}
}
@ -73,7 +74,8 @@ export class PublicConfigClass {
enableOnScrollRendering: true,
enableOnScrollThumbnailPrioritising: true,
authenticationRequired: true,
publicUrl: ""
publicUrl: "",
languages: []
};
}

View File

@ -3,7 +3,7 @@
<div class="panel panel-default" *ngIf="notificationService.notifications.length>0">
<div class="panel-heading">
<h3 class="panel-title">Server notifications</h3>
<h3 class="panel-title" i18n>Server notifications</h3>
</div>
<div class="panel-body">
<ng-container *ngFor="let notification of notificationService.notifications">
@ -16,14 +16,14 @@
</ng-container>
</div>
<div class="panel-footer">
<div class="panel-footer" i18n>
To dismiss these notifications, restart the server.
</div>
</div>
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-10 control-label" for="simplifiedMode">Mode</label>
<div class="col-sm-2">
<label class="col-sm-10 col-xs-8 control-label" for="simplifiedMode" i18n>Mode</label>
<div class="col-sm-2 col-xs-4">
<bSwitch
id="simplifiedMode"
class="switch"

View File

@ -47,6 +47,7 @@ import {NavigationService} from "./model/navigation.service";
import {InfoPanelLightboxComponent} from "./gallery/lightbox/infopanel/info-panel.lightbox.gallery.component";
import {MapSettingsComponent} from "./settings/map/map.settings.component";
import {TooltipModule} from "ngx-bootstrap/tooltip";
import {BsDropdownModule} from "ngx-bootstrap/dropdown";
import {ThumbnailSettingsComponent} from "./settings/thumbnail/thumbanil.settings.component";
import {SearchSettingsComponent} from "./settings/search/search.settings.component";
import {SettingsService} from "./settings/settings.service";
@ -55,6 +56,7 @@ import {BasicSettingsComponent} from "./settings/basic/basic.settings.component"
import {OtherSettingsComponent} from "./settings/other/other.settings.component";
import {DefaultUrlSerializer, UrlSerializer, UrlTree} from '@angular/router';
import {IndexingSettingsComponent} from "./settings/indexing/indexing.settings.component";
import {LanguageComponent} from "./language/language.component";
@Injectable()
export class GoogleMapsConfig {
@ -98,6 +100,7 @@ export class CustomUrlSerializer implements UrlSerializer {
TooltipModule.forRoot(),
ToastModule.forRoot(),
ModalModule.forRoot(),
BsDropdownModule.forRoot(),
AgmCoreModule.forRoot(),
SlimLoadingBarModule.forRoot()
],
@ -105,7 +108,9 @@ export class CustomUrlSerializer implements UrlSerializer {
LoginComponent,
ShareLoginComponent,
GalleryComponent,
//misc
FrameComponent,
LanguageComponent,
//Gallery
GalleryLightboxPhotoComponent,
GalleryPhotoLoadingComponent,

View File

@ -48,3 +48,8 @@ ng2-slim-loading-bar {
padding: 0;
background-color: transparent;
}
language {
display: block;
margin-right: 10px;
}

View File

@ -16,7 +16,7 @@
{{title}}</a>
</div>
<div id="navbar" class="collapse navbar-collapse" [ngClass]="{ 'in': isIn }">
<ul class="nav navbar-nav">
<ul class="nav navbar-nav">$
</ul>
<ul class="nav navbar-nav navbar-right">
@ -35,10 +35,15 @@
<span *ngIf="notificationService.notifications.length>0" class="badge">{{notificationService.notifications.length}}</span>
</a>
</li>
<li>
<language class="navbar-btn"></language>
</li>
<li *ngIf="authenticationRequired">
<button class="btn btn-default navbar-btn"
style="cursor: pointer"
(click)="logout()">Logout <span class="glyphicon glyphicon-log-out" aria-hidden="true"></span>
(click)="logout()">
<ng-container i18n>Logout</ng-container>
<span class="glyphicon glyphicon-log-out" aria-hidden="true"></span>
</button>
</li>
</ul>

View File

@ -4,7 +4,11 @@
<ng-container navbar>
<li *ngIf="countDown">
<p class="navbar-text">Link availability: {{countDown.day}} days,
<p class="navbar-text">
<ng-container i18n>Link availability</ng-container>
: {{countDown.day}}
<ng-container i18n>days</ng-container>
,
{{("0"+countDown.hour).slice(-2)}}:{{("0"+countDown.minute).slice(-2)}}:{{("0"+countDown.second).slice(-2)}}
</p>
</li>
@ -32,12 +36,12 @@
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.searchResult">
<div class="alert alert-info" role="alert"
*ngIf="_galleryService.content.value.searchResult.resultOverflow == true">
*ngIf="_galleryService.content.value.searchResult.resultOverflow == true" i18n>
Too many results to show. Refine your search.
</div>
<ol class="breadcrumb">
<li class="active">
Searching for:
<ng-container i18n>Searching for:</ng-container>
<span [ngSwitch]="_galleryService.content.value.searchResult.searchType">
<span *ngSwitchCase="0" class="glyphicon glyphicon-picture"></span>
<span *ngSwitchCase="1" class="glyphicon glyphicon-folder-open"></span>

View File

@ -2,7 +2,7 @@
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h1 class="modal-title">Info</h1>
<h1 class="modal-title" i18n>Info</h1>
</div>
<div class="row">
<div class="col-xs-2">

View File

@ -50,7 +50,6 @@ export class GalleryNavigatorComponent implements OnChanges {
arr.push({name: "Images", route: null});
} else {
arr.push({name: "Images", route: UserDTO.isPathAvailable("/", user.permissions) ? "/" : null});
}
//create rest navigation

View File

@ -2,6 +2,7 @@
<div class="input-group">
<input type="text"
class="form-control"
i18n-placeholder
placeholder="Search"
(keyup)="onSearchChange($event)"
(blur)="onFocusLost()"

View File

@ -1,7 +1,7 @@
<button id="shareButton" class="btn btn-default navbar-btn btn-link"
type="button" [disabled]="!enabled" (click)="showModal()">
<span class="glyphicon glyphicon-share-alt"></span>
Share
<ng-container i18n>Share</ng-container>
</button>
<!-- sharing Modal-->
@ -15,7 +15,7 @@
<div class="modal-header">
<button type="button" class="close" (click)="hideModal()" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="shareModalLabel">Share</h4>
<h4 class="modal-title" id="shareModalLabel" i18n>Share</h4>
</div>
<div class="modal-body">
<div class="row">
@ -31,14 +31,14 @@
<button id="copyButton" name="copyButton"
ngxClipboard [cbContent]="url"
(cbOnSuccess)="onCopy()"
class="btn btn-primary">Copy
class="btn btn-primary" i18n>Copy
</button>
</div>
</div>
<hr/>
<div class="row">
<div class="col-sm-2">
<label class="control-label">Sharing:</label>
<label class="control-label" i18n>Sharing:</label>
</div>
<div class="col-sm-10">
<input disabled type="text"
@ -49,7 +49,7 @@
<div class="row">
<div class="col-sm-2">
<label class="control-label">Include subfolders:</label>
<label class="control-label" i18n>Include subfolders:</label>
</div>
<div class="col-sm-4">
<input id="recursiveShareBox"
@ -63,7 +63,9 @@
<div class="row">
<div class="col-sm-2">
<label class="control-label">Password:</label>
<label class="control-label">
<ng-container i18n>Password</ng-container>
:</label>
</div>
<div class="col-sm-4">
<input id="password"
@ -77,7 +79,7 @@
<div class="row">
<div class="col-sm-2">
<label class="control-label">Valid:</label>
<label class="control-label" i18n>Valid:</label>
</div>
<div class="col-sm-3" style="padding-right: 1px">
<input class="form-control" [(ngModel)]="input.valid.amount" (change)="update()"

View File

@ -0,0 +1,3 @@
.dropdown-menu {
min-width: auto;
}

View File

@ -0,0 +1,21 @@
<div class="dropdown" dropdown>
<button dropdownToggle
class="btn btn-default dropdown-toggle"
type="button"
id="language"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true">
<ng-container *ngIf="current != null">
{{current}}
</ng-container>
<span *ngIf="current == null" class="glyphicon glyphicon-globe">
</span>
<span class="caret"></span>
</button>
<ul *dropdownMenu class="dropdown-menu" aria-labelledby="language">
<li *ngFor="let lang of languages">
<a href="/{{lang}}">{{lang}}</a>
</li>
</ul>
</div>

View File

@ -0,0 +1,26 @@
import {Component} from "@angular/core";
import {Config} from "../../../common/config/public/Config";
import {Cookie} from "ng2-cookies";
import {CookieNames} from "../../../common/CookieNames";
@Component({
selector: 'language',
templateUrl: './language.component.html',
styleUrls: ['./language.component.css'],
})
export class LanguageComponent {
languages: string[] = [];
current: string = null;
constructor() {
this.languages = Config.Client.languages;
if (Cookie.get(CookieNames.lang) != null) {
this.current = Cookie.get(CookieNames.lang);
}
console.log(this.current);
}
}

View File

@ -61,7 +61,7 @@
color: #d9534f;
}
button {
.btn-login {
width: 100%;
font-size: 18px;
}

View File

@ -1,21 +1,24 @@
<div class="container">
<div class="row">
<language class="pull-right"></language>
</div>
<div class="row title">
<h1><img src="assets/icon.png"/>{{title}}</h1>
</div>
<div class="row card">
<div class="col-md-12">
<h1>Please log in</h1>
<h1 i18n>Please log in</h1>
<form name="form" id="form" class="form-horizontal" #LoginForm="ngForm" (submit)="onLogin()">
<div class="error-message">
{{loginError}}&nbsp;
<div class="error-message" [hidden]="loginError==false" i18n>
Wrong username or password
</div>
<div class="input-group has-margin">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input id="username"
type="text"
class="form-control"
i18n-placeholder
placeholder="Username"
autofocus
[(ngModel)]="loginCredential.username"
@ -29,21 +32,26 @@
type="password"
[(ngModel)]="loginCredential.password"
name="password"
i18n-placeholder
placeholder="Password"
required>
</div>
<div class="checkbox">
<label><input type="checkbox" name="rememberMe" [(ngModel)]="loginCredential.rememberMe" value="">Remember me</label>
<label><input type="checkbox" name="rememberMe" [(ngModel)]="loginCredential.rememberMe" value="">
<ng-container i18n>Remember
me
</ng-container>
</label>
</div>
<div class="form-group">
<!-- Button -->
<div class="col-sm-12 controls">
<button class="btn btn-primary pull-right"
<button class="btn btn-primary pull-right btn-login"
[disabled]="!LoginForm.form.valid || inProgress"
type="submit"
name="action">Login
name="action" i18n>Login
</button>
</div>
</div>

View File

@ -12,7 +12,7 @@ import {NavigationService} from "../model/navigation.service";
})
export class LoginComponent implements OnInit {
loginCredential: LoginCredential;
loginError: any = null;
loginError: boolean = false;
title: string;
inProgress = false;
@ -28,14 +28,14 @@ export class LoginComponent implements OnInit {
}
async onLogin() {
this.loginError = null;
this.loginError = false;
this.inProgress = true;
try {
await this._authService.login(this.loginCredential);
} catch (error) {
if (error && error.code === ErrorCodes.CREDENTIAL_NOT_FOUND) {
this.loginError = "Wrong username or password";
this.loginError = true;
}
}

View File

@ -7,6 +7,7 @@ import {Cookie} from "ng2-cookies";
import {Config} from "../../../../common/config/public/Config";
import {NetworkService} from "./network.service";
import {ErrorCodes, ErrorDTO} from "../../../../common/entities/Error";
import {CookieNames} from "../../../../common/CookieNames";
declare module ServerInject {
export let user: UserDTO;
@ -22,7 +23,7 @@ export class AuthenticationService {
this.user = new BehaviorSubject(null);
//picking up session..
if (this.isAuthenticated() == false && Cookie.get('pigallery2-session') != null) {
if (this.isAuthenticated() == false && Cookie.get(CookieNames.session) != null) {
if (typeof ServerInject !== "undefined" && typeof ServerInject.user !== "undefined") {
this.user.next(ServerInject.user);
}

View File

@ -1,14 +1,14 @@
<form #settingsForm="ngForm" class="form-horizontal">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Basic settings</h3>
<h3 class="panel-title" i18n>Basic settings</h3>
</div>
<div class="panel-body">
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
<div class="form-group" [hidden]="simplifiedMode">
<label class="col-sm-2 control-label" for="applicationTitle">Page title</label>
<label class="col-sm-2 control-label" for="applicationTitle" i18n>Page title</label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="Pigallery 2"
id="applicationTitle"
@ -26,7 +26,7 @@
max="65535"
[(ngModel)]="settings.port"
name="port" required>
<span class="help-block">Port number. Port 80 is usually what you need.</span>
<span class="help-block" i18n>Port number. Port 80 is usually what you need.</span>
</div>
</div>
@ -37,27 +37,27 @@
id="folder"
[(ngModel)]="settings.imagesFolder"
name="folder" required>
<span class="help-block">Images are loaded from this folder (read permission required)</span>
<span class="help-block" i18n>Images are loaded from this folder (read permission required)</span>
</div>
</div>
<div class="form-group" [hidden]="simplifiedMode">
<label class="col-sm-2 control-label" for="publicUrl">Page public url</label>
<label class="col-sm-2 control-label" for="publicUrl" i18n>Page public url</label>
<div class="col-sm-10">
<input type="url" class="form-control" placeholder="{{urlPlaceholder}}"
id="publicUrl"
[(ngModel)]="settings.publicUrl"
name="publicUrl">
<span class="help-block">If you access the page form local network its good to know the public url for creating sharing link</span>
<span class="help-block" i18n>If you access the page form local network its good to know the public url for creating sharing link</span>
</div>
</div>
<button class="btn btn-success pull-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
(click)="save()">Save
(click)="save()" i18n>Save
</button>
<button class="btn btn-default pull-right"
(click)="reset()">Reset
(click)="reset()" i18n>Reset
</button>
</div>
</div>

View File

@ -1,31 +1,31 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Database settings</h3>
<h3 class="panel-title" i18n>Database settings</h3>
</div>
<div class="panel-body">
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
<form #settingsForm="ngForm">
<p class="title">Type:</p>
<p class="title" i18n>Type:</p>
<select class="form-control" [(ngModel)]="settings.type" name="type" required>
<option *ngFor="let type of types" [ngValue]="type.key">{{type.value}}
</option>
</select>
<span *ngIf="settings.type == DatabaseType.mysql"
class="help-block">Install manually mysql node module to use mysql (npm install mysql)</span>
class="help-block" i18n>Install manually mysql node module to use mysql (npm install mysql)</span>
<ng-container *ngIf="settings.type == DatabaseType.mysql">
<p class="title">MySQL settings:</p>
<input type="text" class="form-control" placeholder="Host" autofocus
<p class="title" i18n>MySQL settings:</p>
<input type="text" class="form-control" i18n-placeholder placeholder="Host" autofocus
[(ngModel)]="settings.mysql.host" name="host" required>
<input type="text" class="form-control" placeholder="Database" autofocus
<input type="text" class="form-control" i18n-placeholder placeholder="Database" autofocus
[(ngModel)]="settings.mysql.database" name="database" required>
<input type="text" class="form-control" placeholder="Username"
<input type="text" class="form-control" i18n-placeholder placeholder="Username"
[(ngModel)]="settings.mysql.username" name="username">
<input type="password" class="form-control" placeholder="Password"
<input type="password" class="form-control" i18n-placeholder placeholder="Password"
[(ngModel)]="settings.mysql.password" name="password">
</ng-container>
<ng-container *ngIf="settings.type == DatabaseType.sqlite">
<p class="title">SQLie settings:</p>
<p class="title" i18n>SQLie settings:</p>
<input type="text" class="form-control" placeholder="storage" autofocus
[(ngModel)]="settings.sqlite.storage" name="host" required>
</ng-container>
@ -33,10 +33,10 @@
</form>
<button class="btn btn-success pull-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
(click)="save()">Save
(click)="save()" i18n>Save
</button>
<button class="btn btn-default pull-right"
(click)="reset()">Reset
(click)="reset()" i18n>Reset
</button>
</div>
</div>

View File

@ -1,14 +1,14 @@
<form #settingsForm="ngForm" class="form-horizontal">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title col-xs-4">Folder indexing</h3>
<h3 class="panel-title col-xs-4" i18n>Folder indexing</h3>
</div>
<div class="panel-body">
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
<ng-container *ngIf="!simplifiedMode">
<div class="form-group">
<label class="col-sm-2 control-label" for="cachedFolderTimeout">Index cache timeout [ms]</label>
<label class="col-sm-2 control-label" for="cachedFolderTimeout" i18n>Index cache timeout [ms]</label>
<div class="col-sm-10">
<input type="number" class="form-control" placeholder="36000"
id="cachedFolderTimeout"
@ -16,11 +16,11 @@
step="1"
[(ngModel)]="settings.cachedFolderTimeout"
name="cachedFolderTimeout" required>
<span class="help-block">If there was no indexing in this time, it reindexes. (skipped if indexen in DB and sensitivity is low)</span>
<span class="help-block" i18n>If there was no indexing in this time, it reindexes. (skipped if indexen in DB and sensitivity is low)</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="folderPreviewSize">Sub folder preview size</label>
<label class="col-sm-2 control-label" for="folderPreviewSize" i18n>Sub folder preview size</label>
<div class="col-sm-10">
<input type="number" class="form-control" placeholder="1"
id="folderPreviewSize"
@ -28,12 +28,12 @@
step="1"
[(ngModel)]="settings.folderPreviewSize"
name="folderPreviewSize" required>
<span class="help-block">Reads this many photos from sub folders</span>
<span class="help-block" i18n>Reads this many photos from sub folders</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="reIndexingSensitivity">Folder reindexing sensitivity</label>
<label class="col-sm-2 control-label" for="reIndexingSensitivity" i18n>Folder reindexing sensitivity</label>
<div class="col-sm-10">
<select id="reIndexingSensitivity" class="form-control" [(ngModel)]="settings.reIndexingSensitivity"
name="reIndexingSensitivity" required>
@ -41,24 +41,30 @@
</option>
</select>
<span
class="help-block">Set the reindexing sensitivity. High value check the folders for change more often</span>
class="help-block"
i18n>Set the reindexing sensitivity. High value check the folders for change more often</span>
</div>
</div>
<button class="btn btn-success pull-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
(click)="save()">Save
(click)="save()" i18n>Save
</button>
<button class="btn btn-default pull-right"
(click)="reset()">Reset
(click)="reset()" i18n>Reset
</button>
<br/>
<hr/>
</ng-container>
If you add a new folder to your gallery, the site indexes it automatically.
If you would like to trigger indexing manually, click index button.<br/>
(Note: search ony searched among the indexed directories)<br/>
<ng-container i18n>If you add a new folder to your gallery, the site indexes it automatically.</ng-container>
<ng-container i18n>If you would like to trigger indexing manually, click index button.</ng-container>
<br/>
(
<ng-container i18n>Note: search ony searched among the indexed directories</ng-container>
)<br/>
<div *ngIf="_settingsService.progress.value != null">
indexing: {{_settingsService.progress.value.current}}
@ -79,16 +85,16 @@
<button class="btn btn-success"
*ngIf="_settingsService.progress.value == null"
[disabled]="inProgress"
(click)="index()">Index
(click)="index()" i18n>Index
</button>
<button class="btn btn-default"
*ngIf="_settingsService.progress.value != null"
[disabled]="inProgress"
(click)="cancelIndexing()">Cancel
(click)="cancelIndexing()" i18n>Cancel
</button>
<button class="btn btn-danger"
[disabled]="inProgress"
(click)="resetDatabase()">Reset Indexes
(click)="resetDatabase()" i18n>Reset Indexes
</button>
</div>
</div>

View File

@ -1,7 +1,7 @@
<form #settingsForm="ngForm" class="form-horizontal">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title col-xs-4">Map settings</h3>
<h3 class="panel-title col-xs-4" i18n>Map settings</h3>
<div class="switch-wrapper col-xs-8">
<bSwitch
class="switch"
@ -22,14 +22,15 @@
<div class="form-group">
<label class="col-sm-2 control-label" for="googleApiKey">Google maps api key</label>
<label class="col-sm-2 control-label" for="googleApiKey" i18n>Google maps api key</label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="Google api key"
[(ngModel)]="settings.googleApiKey"
[disabled]="!settings.enabled"
name="googleApiKey" id="googleApiKey" required>
<span class="help-block">To show the images on a map, <a
href="https://developers.google.com/maps/documentation/javascript/get-api-key">google api key</a> is need</span>
<span class="help-block"><ng-container i18n>To show the images on a map,</ng-container> <a
href="https://developers.google.com/maps/documentation/javascript/get-api-key" i18n>google api key</a> <ng-container
i18n>is need</ng-container></span>
</div>
@ -37,10 +38,10 @@
<button class="btn btn-success pull-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
(click)="save()">Save
(click)="save()" i18n>Save
</button>
<button class="btn btn-default pull-right"
(click)="reset()">Reset
(click)="reset()" i18n>Reset
</button>
</div>
</div>

View File

@ -1,14 +1,14 @@
<form #settingsForm="ngForm" class="form-horizontal">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Other settings</h3>
<h3 class="panel-title" i18n>Other settings</h3>
</div>
<div class="panel-body">
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong i18n>Error: </strong>{{error}}</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="enableThreading">Threading</label>
<label class="col-sm-2 control-label" for="enableThreading" i18n>Threading</label>
<div class="col-sm-10">
<bSwitch
id="enableThreading"
@ -22,12 +22,12 @@
[switch-label-width]="'20'"
[(ngModel)]="settings.enableThreading">
</bSwitch>
<span class="help-block">Runs directory scanning and thumbnail generation (only for Jimp) in a different thread</span>
<span class="help-block" i18n>Runs directory scanning and thumbnail generation (only for Jimp) in a different thread</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="enableOnScrollThumbnailPrioritising">Scroll based thumbnail
<label class="col-sm-2 control-label" for="enableOnScrollThumbnailPrioritising" i18n>Scroll based thumbnail
generation</label>
<div class="col-sm-10">
<bSwitch
@ -42,12 +42,12 @@
[switch-label-width]="'20'"
[(ngModel)]="settings.enableOnScrollThumbnailPrioritising">
</bSwitch>
<span class="help-block">Those thumbnails get higher priority that are visible on the screen</span>
<span class="help-block" i18n>Those thumbnails get higher priority that are visible on the screen</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="enableOnScrollRendering">Lazy image rendering</label>
<label class="col-sm-2 control-label" for="enableOnScrollRendering" i18n>Lazy image rendering</label>
<div class="col-sm-10">
<bSwitch
id="enableOnScrollRendering"
@ -61,13 +61,13 @@
[switch-label-width]="'20'"
[(ngModel)]="settings.enableOnScrollRendering">
</bSwitch>
<span class="help-block">Shows only the required amount of photos at once. Renders more if page bottom is reached</span>
<span class="help-block" i18n>Shows only the required amount of photos at once. Renders more if page bottom is reached</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="enableCache">Cache</label>
<label class="col-sm-2 control-label" for="enableCache" i18n>Cache</label>
<div class="col-sm-10">
<bSwitch
id="enableCache"
@ -81,17 +81,17 @@
[switch-label-width]="'20'"
[(ngModel)]="settings.enableCache">
</bSwitch>
<span class="help-block">Caches directory contents and search results for better performance</span>
<span class="help-block" i18n>Caches directory contents and search results for better performance</span>
</div>
</div>
<button class="btn btn-success pull-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
(click)="save()">Save
(click)="save()" i18n>Save
</button>
<button class="btn btn-default pull-right"
(click)="reset()">Reset
(click)="reset()" i18n>Reset
</button>
</div>
</div>

View File

@ -2,7 +2,7 @@
<div class="panel panel-default"
[ngClass]="settings.enabled && !_settingsService.isSupported()?'panel-warning':''">
<div class="panel-heading">
<h3 class="panel-title col-xs-6">Search settings</h3>
<h3 class="panel-title col-xs-6" i18n>Search settings</h3>
<div class="switch-wrapper col-xs-6">
<bSwitch
class="switch"
@ -24,7 +24,7 @@
<ng-container *ngIf="settings.enabled || _settingsService.isSupported()">
<div class="form-group">
<label class="col-sm-2 control-label" for="autocompleteEnabled">Autocomplete</label>
<label class="col-sm-2 control-label" for="autocompleteEnabled" i18n>Autocomplete</label>
<div class="col-sm-10">
<bSwitch
id="autocompleteEnabled"
@ -39,13 +39,13 @@
[switch-label-width]="'20'"
[(ngModel)]="settings.autocompleteEnabled">
</bSwitch>
<span class="help-block">Show hints while typing search query</span>
<span class="help-block" i18n>Show hints while typing search query</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="instantSearchEnabled">Instant search</label>
<label class="col-sm-2 control-label" for="instantSearchEnabled" i18n>Instant search</label>
<div class="col-sm-10">
<bSwitch
id="instantSearchEnabled"
@ -60,20 +60,20 @@
[switch-label-width]="'20'"
[(ngModel)]="settings.instantSearchEnabled">
</bSwitch>
<span class="help-block">Enables showing search results, while typing search query</span>
<span class="help-block" i18n>Enables showing search results, while typing search query</span>
</div>
</div>
</ng-container>
<div class="panel-info" *ngIf="(!settings.enabled && !_settingsService.isSupported())">
<div class="panel-info" *ngIf="(!settings.enabled && !_settingsService.isSupported())" i18n>
Search is not supported with these settings
</div>
<button class="btn btn-success pull-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
(click)="save()">Save
(click)="save()" i18n>Save
</button>
<button class="btn btn-default pull-right"
(click)="reset()">Reset
(click)="reset()" i18n>Reset
</button>
</div>
</div>

View File

@ -1,9 +1,7 @@
import {Injectable} from "@angular/core";
import {BehaviorSubject} from "rxjs/BehaviorSubject";
import {
DatabaseType,
IPrivateConfig,
ReIndexingSensitivity,
DatabaseType, IPrivateConfig, ReIndexingSensitivity,
ThumbnailProcessingLib
} from "../../../common/config/private/IPrivateConfig";
import {NetworkService} from "../model/network/network.service";
@ -42,7 +40,8 @@ export class SettingsService {
enableCache: true,
enableOnScrollRendering: true,
enableOnScrollThumbnailPrioritising: true,
authenticationRequired: true
authenticationRequired: true,
languages: []
},
Server: {
database: {

View File

@ -2,7 +2,7 @@
<div class="panel panel-default"
[ngClass]="settings.enabled && !_settingsService.isSupported()?'panel-warning':''">
<div class="panel-heading">
<h3 class="panel-title col-xs-6">Share settings</h3>
<h3 class="panel-title col-xs-6" i18n>Share settings</h3>
<div class="switch-wrapper col-xs-6">
<bSwitch
class="switch"
@ -23,7 +23,7 @@
<ng-container *ngIf="settings.enabled || _settingsService.isSupported()">
<div class="form-group">
<label class="col-sm-2 control-label" for="passwordProtected">Password protected</label>
<label class="col-sm-2 control-label" for="passwordProtected" i18n>Password protected</label>
<div class="col-sm-10">
<bSwitch
id="passwordProtected"
@ -38,21 +38,21 @@
[switch-label-width]="'20'"
[(ngModel)]="settings.passwordProtected">
</bSwitch>
<span class="help-block">Enables password protected sharing links</span>
<span class="help-block" i18n>Enables password protected sharing links</span>
</div>
</div>
</ng-container>
<div class="panel-info" *ngIf="(!settings.enabled && !_settingsService.isSupported())">
<div class="panel-info" *ngIf="(!settings.enabled && !_settingsService.isSupported())" i18n>
Sharing is not supported with these settings
</div>
<button class="btn btn-success pull-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
(click)="save()">Save
(click)="save()" i18n>Save
</button>
<button class="btn btn-default pull-right"
(click)="reset()">Reset
(click)="reset()" i18n>Reset
</button>
</div>
</div>

View File

@ -1,18 +1,19 @@
<form #settingsForm="ngForm" class="form-horizontal">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Thumbnail settings</h3>
<h3 class="panel-title" i18n>Thumbnail settings</h3>
</div>
<div class="panel-body">
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
<div [hidden]="settings.server.processingLibrary!=ThumbnailProcessingLib.Jimp"
class="alert alert-warning"
role="alert">It is highly recommended to use hardware accelerated (sharp or gm) lib for thumbnail generation
role="alert" i18n>It is highly recommended to use hardware accelerated (sharp or gm) lib for thumbnail
generation
</div>
<fieldset>
<div class="form-group">
<label class="col-sm-2 control-label" for="lib">Thumbnail generation library</label>
<label class="col-sm-2 control-label" for="lib" i18n>Thumbnail generation library</label>
<div class="col-sm-10">
<select id="lib" class="form-control" [(ngModel)]="settings.server.processingLibrary"
name="type" required>
@ -20,27 +21,27 @@
</option>
</select>
<span *ngIf="settings.server.processingLibrary==ThumbnailProcessingLib.sharp"
class="help-block">Make sure that sharp node module is installed (npm install sharp)</span>
class="help-block" i18n>Make sure that sharp node module is installed (npm install sharp).</span>
<span *ngIf="settings.server.processingLibrary==ThumbnailProcessingLib.gm"
class="help-block">Make sure that gm node module and <a
href="http://www.graphicsmagick.org/">GraphicsMagick</a> are installed (npm install sharp)</span>
class="help-block"><ng-container i18n>Make sure that gm node module and</ng-container> <a
href="http://www.graphicsmagick.org/" i18n>GraphicsMagick</a> <ng-container i18n>are installed (npm install sharp).</ng-container></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="th_folder">Thumbnail folder</label>
<label class="col-sm-2 control-label" for="th_folder" i18n>Thumbnail folder</label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="path"
id="th_folder"
[(ngModel)]="settings.server.folder"
name="path" required>
<span class="help-block">Thumbnails will be saved in this folder. Write access is required</span>
<span class="help-block" i18n>Thumbnails will be saved in this folder. Write access is required</span>
</div>
</div>
<div class="form-group" [hidden]="simplifiedMode">
<label class="col-sm-2 control-label" for="quality">Thumbnail Quality</label>
<label class="col-sm-2 control-label" for="quality" i18n>Thumbnail Quality</label>
<div class="col-sm-10">
<bSwitch
id="quality"
@ -54,7 +55,7 @@
[switch-label-width]="'20'"
[(ngModel)]="settings.server.qualityPriority">
</bSwitch>
<span class="help-block">High quality may be slow. Especially with Jimp.</span>
<span class="help-block" i18n>High quality may be slow. Especially with Jimp.</span>
</div>
</div>
@ -69,22 +70,23 @@
max="100"
step="1"
name="icon" required>
<span class="help-block">Icon size (used on maps)</span>
<span class="help-block" i18n>Icon size (used on maps)</span>
</div>
</div>
<div class="form-group" [hidden]="simplifiedMode">
<label class="col-sm-2 control-label" for="thumbnailSizes">Thumbnail sizes</label>
<label class="col-sm-2 control-label" for="thumbnailSizes" i18n>Thumbnail sizes</label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="200; 400"
id="thumbnailSizes"
[(ngModel)]="ThumbnailSizes"
name="thumbnailSizes" required>
<span class="help-block">
Size of the thumbnails.<br/>
The best matching size will be generated. (More size gives better quality, but use storage to store and CPU to render.)<br/>
';' separated integers. If size is 200, tha thumbnail will have 200^2 pixels.
<ng-container i18n>Size of the thumbnails.</ng-container><br/>
<ng-container i18n>The best matching size will be generated. (More size gives better quality, but use storage to store and CPU to render.)</ng-container><br/>
<ng-container
i18n>';' separated integers. If size is 200, tha thumbnail will have 200^2 pixels.</ng-container>
</span>
</div>
@ -93,10 +95,10 @@
<button class="btn btn-success pull-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
(click)="save()">Save
(click)="save()" i18n>Save
</button>
<button class="btn btn-default pull-right"
(click)="reset()">Reset
(click)="reset()" i18n>Reset
</button>
</div>
</div>

View File

@ -1,6 +1,6 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title col-xs-6">Password protection </h3>
<h3 class="panel-title col-xs-6" i18n>Password protection </h3>
<div class="switch-wrapper col-xs-6">
<bSwitch
class="switch"
@ -24,8 +24,8 @@
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Role</th>
<th i18n>Name</th>
<th i18n>Role</th>
<th></th>
</tr>
</thead>
@ -52,11 +52,10 @@
</table>
<button class="btn btn-primary pull-right"
(click)="initNewUser()">+ Add
user
(click)="initNewUser()" i18n>+ Add user
</button>
</ng-container>
<div class="panel-info" *ngIf="!enabled">
<div class="panel-info" *ngIf="!enabled" i18n>
To protect the site with password / have login enable this.
</div>
</div>
@ -70,14 +69,14 @@
<div class="modal-header">
<button type="button" class="close" (click)="userModal.hide()" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="userModalLabel">Add new User</h4>
<h4 class="modal-title" id="userModalLabel" i18n>Add new User</h4>
</div>
<form #NewUserForm="ngForm">
<div class="modal-body">
<input type="text" class="form-control" placeholder="Username" autofocus
<input type="text" class="form-control" i18n-placeholder placeholder="Username" autofocus
[(ngModel)]="newUser.name" name="name" required>
<input type="password" class="form-control" placeholder="Password"
<input type="password" class="form-control" i18n-placeholder placeholder="Password"
[(ngModel)]="newUser.password" name="password" required>
<select class="form-control" [(ngModel)]="newUser.role" name="role" required>
<option *ngFor="let repository of userRoles" [value]="repository.key">{{repository.value}}
@ -85,10 +84,10 @@
</select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" (click)="userModal.hide()">Close</button>
<button type="button" class="btn btn-default" (click)="userModal.hide()" i18n>Close</button>
<button type="button" class="btn btn-primary" data-dismiss="modal"
(click)="addNewUser()"
[disabled]="!NewUserForm.form.valid">Add User
[disabled]="!NewUserForm.form.valid" i18n>Add User
</button>
</div>
</form>

View File

@ -51,7 +51,7 @@
color: #d9534f;
}
button {
.btn-login {
width: 100%;
font-size: 18px;
}

View File

@ -1,5 +1,8 @@
<div class="container">
<div class="row">
<language class="pull-right"></language>
</div>
<div class="row title">
<h1><img src="assets/icon.png"/>{{title}}</h1>
</div>
@ -7,8 +10,8 @@
<div class="row card">
<div class="col-md-12">
<form name="form" id="form" class="form-horizontal" #LoginForm="ngForm" (submit)="onLogin()">
<div class="error-message">
{{loginError}}&nbsp;
<div class="error-message" [hidden]="loginError==false" i18n>
Wrong password
</div>
<div class="input-group has-margin">
@ -18,6 +21,7 @@
type="password"
[(ngModel)]="password"
name="password"
i18n-placeholder
placeholder="Password"
required>
</div>
@ -26,10 +30,10 @@
<div class="form-group">
<!-- Button -->
<div class="col-sm-12 controls">
<button class="btn btn-primary pull-right"
<button class="btn btn-primary pull-right btn-login"
[disabled]="!LoginForm.form.valid"
type="submit"
name="action">Enter
name="action" i18n>Enter
</button>
</div>
</div>

View File

@ -11,7 +11,7 @@ import {NavigationService} from "../model/navigation.service";
})
export class ShareLoginComponent implements OnInit {
password: string;
loginError: any = null;
loginError: boolean = false;
title: string;
constructor(private _authService: AuthenticationService, private _navigation: NavigationService) {
@ -25,14 +25,14 @@ export class ShareLoginComponent implements OnInit {
}
async onLogin() {
this.loginError = null;
this.loginError = false;
try {
await this._authService.shareLogin(this.password);
} catch (error) {
if (error && error.code === ErrorCodes.CREDENTIAL_NOT_FOUND) {
this.loginError = "Wrong password";
this.loginError = true;
}
}
}

View File

@ -11,7 +11,7 @@
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.4/css/bootstrap3/bootstrap-switch.css">
<script type="text/javascript" src="config_inject.js"></script>
<script type="text/javascript" src="/config_inject.js"></script>
</head>

View File

@ -0,0 +1,939 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="380bac8029fe968edf74d1856635666bf8b55516" datatype="html">
<source>Please log in</source>
<context-group purpose="location">
<context context-type="sourcefile">app/login/login.component.ts</context>
<context context-type="linenumber">11</context>
</context-group>
<target>Jelentkezz be</target>
</trans-unit>
<trans-unit id="f5006bd06a75b0b5719b47cd81a516d1a923ef88" datatype="html">
<source>
Wrong username or password
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/login/login.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<target>Hibás felhasználónév vagy jelszó</target>
</trans-unit>
<trans-unit id="08c74dc9762957593b91f6eb5d65efdfc975bf48" datatype="html">
<source>Username</source>
<context-group purpose="location">
<context context-type="sourcefile">app/login/login.component.ts</context>
<context context-type="linenumber">22</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">77</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">22</context>
</context-group>
<target>Felhasználónév</target>
</trans-unit>
<trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407" datatype="html">
<source>Password</source>
<context-group purpose="location">
<context context-type="sourcefile">app/login/login.component.ts</context>
<context context-type="linenumber">36</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/sharelogin/share-login.component.ts</context>
<context context-type="linenumber">25</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/share/share.gallery.component.ts</context>
<context context-type="linenumber">66</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">79</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">24</context>
</context-group>
<target>Jelszó</target>
</trans-unit>
<trans-unit id="c67b8aed16c2f80bd4a8d5df636bb333feaa8c78" datatype="html">
<source>Remember
me</source>
<context-group purpose="location">
<context context-type="sourcefile">app/login/login.component.ts</context>
<context context-type="linenumber">41</context>
</context-group>
<target>Jegyezzen meg</target>
</trans-unit>
<trans-unit id="c15f0f6076dd3f758adb69556fb1751f7a8139dc" datatype="html">
<source>Login
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/login/login.component.ts</context>
<context context-type="linenumber">51</context>
</context-group>
<target>Belépés</target>
</trans-unit>
<trans-unit id="64034510da88fc99130864f733500fcd62aedb01" datatype="html">
<source>
Wrong password
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/sharelogin/share-login.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<target>Hibás jelszó</target>
</trans-unit>
<trans-unit id="7bc15e0478a1384ea38903e2506f4ae3fe7dd6e1" datatype="html">
<source>Enter
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/sharelogin/share-login.component.ts</context>
<context context-type="linenumber">36</context>
</context-group>
<target>Belépés</target>
</trans-unit>
<trans-unit id="7e892ba15f2c6c17e83510e273b3e10fc32ea016" datatype="html">
<source>Search</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/search/search.gallery.component.ts</context>
<context context-type="linenumber">6</context>
</context-group>
<target>Keresés</target>
</trans-unit>
<trans-unit id="f3cda2936c4e70d5b920b2c243ec634222743ba1" datatype="html">
<source>Link availability</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/gallery.component.ts</context>
<context context-type="linenumber">7</context>
</context-group>
<target>Link érvényes</target>
</trans-unit>
<trans-unit id="fc34f2683c4cb526ed7095c5b1cdd66d672ba932" datatype="html">
<source>days</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/gallery.component.ts</context>
<context context-type="linenumber">7</context>
</context-group>
<target>nap</target>
</trans-unit>
<trans-unit id="c17b163553f84f2f704031a1b343e7b89c5c5ee1" datatype="html">
<source>
Too many results to show. Refine your search.
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/gallery.component.ts</context>
<context context-type="linenumber">35</context>
</context-group>
<target>Túl sok találat. Pontosítsd a keresést.</target>
</trans-unit>
<trans-unit id="24f166827601febff9ec90329582bc637781def8" datatype="html">
<source>Searching for:</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/gallery.component.ts</context>
<context context-type="linenumber">40</context>
</context-group>
<target>Keresés:</target>
</trans-unit>
<trans-unit id="bb694b49d408265c91c62799c2b3a7e3151c824d" datatype="html">
<source>Logout</source>
<context-group purpose="location">
<context context-type="sourcefile">app/frame/frame.component.ts</context>
<context context-type="linenumber">44</context>
</context-group>
<target>Kijelentkezés</target>
</trans-unit>
<trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9" datatype="html">
<source>Share</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/share/share.gallery.component.ts</context>
<context context-type="linenumber">4</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/share/share.gallery.component.ts</context>
<context context-type="linenumber">18</context>
</context-group>
<target>Ossza meg</target>
</trans-unit>
<trans-unit id="74f659dedc52d20e191c01d8edc94acbeb972721" datatype="html">
<source>Copy
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/share/share.gallery.component.ts</context>
<context context-type="linenumber">34</context>
</context-group>
<target>Másolás</target>
</trans-unit>
<trans-unit id="07867d2c08ad81d9f1cb27f083c5d32d0d1f3bd6" datatype="html">
<source>Sharing:</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/share/share.gallery.component.ts</context>
<context context-type="linenumber">41</context>
</context-group>
<target>Megosztás:</target>
</trans-unit>
<trans-unit id="030e713e20f553f6c55b76d217e8b604da1ea7c2" datatype="html">
<source>Include subfolders:</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/share/share.gallery.component.ts</context>
<context context-type="linenumber">52</context>
</context-group>
<target>Alkönyvtárakat is:</target>
</trans-unit>
<trans-unit id="ac26f1ef0bc7eb42fdabd901d99cb23728abcd4f" datatype="html">
<source>Valid:</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/share/share.gallery.component.ts</context>
<context context-type="linenumber">80</context>
</context-group>
<target>Érvényes:</target>
</trans-unit>
<trans-unit id="f0acecaa22df19767da6d9990458470b17da3d7a" datatype="html">
<source>Server notifications</source>
<context-group purpose="location">
<context context-type="sourcefile">app/admin/admin.component.ts</context>
<context context-type="linenumber">6</context>
</context-group>
<target>Szerver értesítések</target>
</trans-unit>
<trans-unit id="483d20ced82942e869d34d4592675741a0dfe910" datatype="html">
<source>
To dismiss these notifications, restart the server.
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/admin/admin.component.ts</context>
<context context-type="linenumber">19</context>
</context-group>
<target>Az ilyen értesítések elütetéséhez indítsd újra a az alkalmazást.</target>
</trans-unit>
<trans-unit id="37e10df2d9c0c25ef04ac112c9c9a7723e8efae0" datatype="html">
<source>Mode</source>
<context-group purpose="location">
<context context-type="sourcefile">app/admin/admin.component.ts</context>
<context context-type="linenumber">25</context>
</context-group>
<target>Mód</target>
</trans-unit>
<trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5" datatype="html">
<source>Info</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts</context>
<context context-type="linenumber">5</context>
</context-group>
<target>Info</target>
</trans-unit>
<trans-unit id="343879e5c41bab3cbc6160ae25fb0ed8e08859f0" datatype="html">
<source>Password protection </source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">3</context>
</context-group>
<target>Jelszavas védelem</target>
</trans-unit>
<trans-unit id="cff1428d10d59d14e45edec3c735a27b5482db59" datatype="html">
<source>Name</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">27</context>
</context-group>
<target>Név</target>
</trans-unit>
<trans-unit id="c36a66f2107e8da5371ebc9d15c2008dff567f46" datatype="html">
<source>Role</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">28</context>
</context-group>
<target>Jogkör</target>
</trans-unit>
<trans-unit id="e3fcf58f9472d33a35df59fe5520e3b8b41d6951" datatype="html">
<source>+ Add user
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">55</context>
</context-group>
<target>+ Felhasználó hozzáadása</target>
</trans-unit>
<trans-unit id="eebaef174029db4c77c4f7d1c68070774730f4d3" datatype="html">
<source>
To protect the site with password / have login enable this.
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">58</context>
</context-group>
<target>A webhely jelszóval legyen védve / be kelljen jelentkezni</target>
</trans-unit>
<trans-unit id="2df47a22f05b9ac3bdabb6693d4bc37c3ad7c000" datatype="html">
<source>Add new User</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">72</context>
</context-group>
<target>Új felhasználó hozzáadása</target>
</trans-unit>
<trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
<source>Close</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">87</context>
</context-group>
<target>Bezárás</target>
</trans-unit>
<trans-unit id="b6a518f3a8fcc0357ddd9e9115b66d281b81eb3b" datatype="html">
<source>Add User
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/usermanager/usermanager.settings.component.ts</context>
<context context-type="linenumber">90</context>
</context-group>
<target>Felhasználó hozzáadása</target>
</trans-unit>
<trans-unit id="25e15358423a68caf2960ac3eac6f7cfd19d5a30" datatype="html">
<source>Database settings</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">3</context>
</context-group>
<target>Adatbázis beállítások</target>
</trans-unit>
<trans-unit id="e78c0d60ac39787f62c9159646fe0b3c1ed55a1d" datatype="html">
<source>Type:</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">8</context>
</context-group>
<target>Típus:</target>
</trans-unit>
<trans-unit id="3a0f01d7b9e02e5d692259c94d790957604e6e03" datatype="html">
<source>Install manually mysql node module to use mysql (npm install mysql)</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<target>Telepítsd kézzel mysql node-modult a mysql (npm install mysql) használatához</target>
</trans-unit>
<trans-unit id="1531e77d9dbcfb6a3efeb71fca40da5f5f7ddaaf" datatype="html">
<source>MySQL settings:</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">17</context>
</context-group>
<target>MySQL beállítások:</target>
</trans-unit>
<trans-unit id="fe22ca53e651df951dac25b67c17894b0980f767" datatype="html">
<source>Host</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">18</context>
</context-group>
<target>Cím</target>
</trans-unit>
<trans-unit id="fb324ec7da611c6283caa6fc6257c39a56d6aaf7" datatype="html">
<source>Database</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">20</context>
</context-group>
<target>adatbázis</target>
</trans-unit>
<trans-unit id="5b1d1f76e9702b36014e734fd24aa8c5c486784a" datatype="html">
<source>SQLie settings:</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">28</context>
</context-group>
<target>SQLite beállítások:</target>
</trans-unit>
<trans-unit id="c84df9553019022cc521320e3afaed42f23feca1" datatype="html">
<source>Save
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">36</context>
</context-group>
<target>Mentés</target>
</trans-unit>
<trans-unit id="606e35514c0bf86c3b47babbc76eb1bb4e973cb0" datatype="html">
<source>Reset
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/database/database.settings.component.ts</context>
<context context-type="linenumber">39</context>
</context-group>
<target>Visszaállítás</target>
</trans-unit>
<trans-unit id="808812b8319c389ecbb84c658d5b3eac7087d079" datatype="html">
<source>Map settings</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.ts</context>
<context context-type="linenumber">4</context>
</context-group>
<target>Térképbeállítások</target>
</trans-unit>
<trans-unit id="2ac5d327999abb61d7353f475edffa8b1f0a8ad7" datatype="html">
<source>Google maps api key</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.ts</context>
<context context-type="linenumber">25</context>
</context-group>
<target>Google maps api key</target>
</trans-unit>
<trans-unit id="83d20bb14a5d264b30b919fd3b52903f0b7a124c" datatype="html">
<source>To show the images on a map,</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.ts</context>
<context context-type="linenumber">31</context>
</context-group>
<target>Ahhoz, hogy a térképen megjelenjenek a képek</target>
</trans-unit>
<trans-unit id="9b480df2a8ef25163f0c093fe11c336908c7b55c" datatype="html">
<source>google api key</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.ts</context>
<context context-type="linenumber">32</context>
</context-group>
<target>google api key-re</target>
</trans-unit>
<trans-unit id="0d727eb391d8b787f3195d51625ea8579b05506a" datatype="html">
<source>is need</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.ts</context>
<context context-type="linenumber">32</context>
</context-group>
<target>van szükség</target>
</trans-unit>
<trans-unit id="d682be8fc94c1861394919e021e9dcf8def8f554" datatype="html">
<source>Save
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.ts</context>
<context context-type="linenumber">40</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">96</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/search/search.settings.component.ts</context>
<context context-type="linenumber">73</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/share/share.settings.component.ts</context>
<context context-type="linenumber">52</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/basic/basic.settings.component.ts</context>
<context context-type="linenumber">57</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">91</context>
</context-group>
<target>Mentés</target>
</trans-unit>
<trans-unit id="bdff31ca405839a31596fdb5bfd8ac933289b5e7" datatype="html">
<source>Reset
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.ts</context>
<context context-type="linenumber">43</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/search/search.settings.component.ts</context>
<context context-type="linenumber">76</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/share/share.settings.component.ts</context>
<context context-type="linenumber">55</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/basic/basic.settings.component.ts</context>
<context context-type="linenumber">60</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">94</context>
</context-group>
<target>Visszaállítás</target>
</trans-unit>
<trans-unit id="d6644690d6218f5ecc21dd3b2c69aca33d6d58c3" datatype="html">
<source>Thumbnail settings</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">4</context>
</context-group>
<target>Thumbnail beállítások</target>
</trans-unit>
<trans-unit id="6daacb1e448ebb5f72f1d6b1d6f9882dd3ad21f2" datatype="html">
<source>It is highly recommended to use hardware accelerated (sharp or gm) lib for thumbnail generation
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">10</context>
</context-group>
<target>Nagyon ajánlott hardveresen gyorsított (sharp vagy gm) könyvtár használata a thumbnail generálásához</target>
</trans-unit>
<trans-unit id="6f49ee2673fb82fe8dd1a7da0bada14a4156bf30" datatype="html">
<source>Thumbnail generation library</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">15</context>
</context-group>
<target>Thumbnail generáló könyvtár</target>
</trans-unit>
<trans-unit id="405e524b190e5a9325aa74a21736f05afbf0fe6c" datatype="html">
<source>Make sure that sharp node module is installed (npm install sharp).</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">23</context>
</context-group>
<target>Győződj meg arról, hogy a sharp node modul telepítve van (npm telepítés sharp).</target>
</trans-unit>
<trans-unit id="becf05481d292e5e206fda4b7d67d8fac4e85c93" datatype="html">
<source>Make sure that gm node module and</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">25</context>
</context-group>
<target>Győződjd meg arról, hogy a gm node modul és</target>
</trans-unit>
<trans-unit id="50baaa30462f55de8e9b80d5762048f7ba4cecc4" datatype="html">
<source>GraphicsMagick</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">26</context>
</context-group>
<target>GraphicsMagick</target>
</trans-unit>
<trans-unit id="b3dc2b50f4949565d88efab1f3ebd4236e16a082" datatype="html">
<source>are installed (npm install sharp).</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">26</context>
</context-group>
<target>telepítve van (npm install éles).</target>
</trans-unit>
<trans-unit id="77dbc5bc9bc2a7dfc5394da0dcf5f08e4a120502" datatype="html">
<source>Thumbnail folder</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">32</context>
</context-group>
<target>Thumbnail mappa</target>
</trans-unit>
<trans-unit id="2e849a0c704352d5f4615880f47aea06025566f4" datatype="html">
<source>Thumbnails will be saved in this folder. Write access is required</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">38</context>
</context-group>
<target>A thumbnail-ek ebben a mappában lesznek elmentve. Írási jog szükséges</target>
</trans-unit>
<trans-unit id="76a16cf361d95615469c06e26644b6e52f3a4411" datatype="html">
<source>Thumbnail Quality</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">43</context>
</context-group>
<target>Thumbnail minőség</target>
</trans-unit>
<trans-unit id="b2d8e74a49c92e56ab68a248c5090187b16da0ae" datatype="html">
<source>High quality may be slow. Especially with Jimp.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">57</context>
</context-group>
<target>A jó minőségű lassú lehet. Különösen a Jimp esetén.</target>
</trans-unit>
<trans-unit id="b1a101e4cac6b5af1e4710d01ad2da24b494e982" datatype="html">
<source>Icon size (used on maps)</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">72</context>
</context-group>
<target>Ikonméret (térképeken használva)</target>
</trans-unit>
<trans-unit id="695e937f7b52084765c07a2b1269a040024a2363" datatype="html">
<source>Thumbnail sizes</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">78</context>
</context-group>
<target>Thumbnail méretek</target>
</trans-unit>
<trans-unit id="ccfcda4d4700752fafcce0d40a3a6765056c200a" datatype="html">
<source>Size of the thumbnails.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">85</context>
</context-group>
<target>A thumbnail mérete.</target>
</trans-unit>
<trans-unit id="11b5800486a59a25fad47fa9850420f83ccbe52b" datatype="html">
<source>The best matching size will be generated. (More size gives better quality, but use storage to store and CPU to render.)</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">86</context>
</context-group>
<target>A legjobban egyezett méret lesz generálva. (Több méret lehetőség jobb minőségéet eredményez, de processzort és tárhelyet fogyaszt)</target>
</trans-unit>
<trans-unit id="5c43f65d4b1e7f4c12937babb0794e7b84a9a103" datatype="html">
<source>';' separated integers. If size is 200, tha thumbnail will have 200^2 pixels.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.ts</context>
<context context-type="linenumber">87</context>
</context-group>
<target>';'-val elválasztott egész számok. Ha a méret 200, akkor a thumnail-ok 200^2 pixelből fognak állni.</target>
</trans-unit>
<trans-unit id="2e75ae3885931555902da6b288ed616843d5dc3c" datatype="html">
<source>Search settings</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/search/search.settings.component.ts</context>
<context context-type="linenumber">5</context>
</context-group>
<target>Keresési beállítások</target>
</trans-unit>
<trans-unit id="fba3e700d434667e68ec31f38b2fed451955b6a3" datatype="html">
<source>Autocomplete</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/search/search.settings.component.ts</context>
<context context-type="linenumber">27</context>
</context-group>
<target>Automatikus kiegészítés</target>
</trans-unit>
<trans-unit id="3370f9ec1e5b41b30e8c1e0de57d4dfacd0e1360" datatype="html">
<source>Show hints while typing search query</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/search/search.settings.component.ts</context>
<context context-type="linenumber">42</context>
</context-group>
<target>Kersési javaslatok megjelenítése a keresési szöveg beírása közben</target>
</trans-unit>
<trans-unit id="4f3e132bcb74ee7c0a19eff3915163699c249340" datatype="html">
<source>Instant search</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/search/search.settings.component.ts</context>
<context context-type="linenumber">48</context>
</context-group>
<target>Azonnali (instant) keresés</target>
</trans-unit>
<trans-unit id="d532897643597c8670a76f65514b4cf92990729f" datatype="html">
<source>Enables showing search results, while typing search query</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/search/search.settings.component.ts</context>
<context context-type="linenumber">63</context>
</context-group>
<target>Lehetővé teszi a keresési eredmények megjelenítését a keresés beírása közben</target>
</trans-unit>
<trans-unit id="fca20aaca9607b7bcfd32718fa299d107c73c32a" datatype="html">
<source>
Search is not supported with these settings
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/search/search.settings.component.ts</context>
<context context-type="linenumber">68</context>
</context-group>
<target>A keresés nem támogatott ezekkel a beállításokkal</target>
</trans-unit>
<trans-unit id="2ca3f59b3fe47e837455e9090470356d27d1f59e" datatype="html">
<source>Share settings</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/share/share.settings.component.ts</context>
<context context-type="linenumber">5</context>
</context-group>
<target>Megosztási bállítások</target>
</trans-unit>
<trans-unit id="6024b74e5baa9004f52b2d91fe37321412e328e4" datatype="html">
<source>Password protected</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/share/share.settings.component.ts</context>
<context context-type="linenumber">26</context>
</context-group>
<target>Jelszóval védett</target>
</trans-unit>
<trans-unit id="0ea62fbed498f782a8d0cb876e2f8a8fff8ed6ed" datatype="html">
<source>Enables password protected sharing links</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/share/share.settings.component.ts</context>
<context context-type="linenumber">41</context>
</context-group>
<target>Jelszóval védi a megoszott linkeket.</target>
</trans-unit>
<trans-unit id="ec3e07d68edadc3aa5ad84f316e43f739a2bd962" datatype="html">
<source>
Sharing is not supported with these settings
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/share/share.settings.component.ts</context>
<context context-type="linenumber">47</context>
</context-group>
<target>A megosztás nem támogatott ezekkel a beállításokkal</target>
</trans-unit>
<trans-unit id="fe4fefb86d4b6629064ff0fa96fdc2b80fc151b0" datatype="html">
<source>Basic settings</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/basic/basic.settings.component.ts</context>
<context context-type="linenumber">4</context>
</context-group>
<target>Egyszerű beállítások</target>
</trans-unit>
<trans-unit id="870d05214ce19848ea4b7fe698e9a2e73db0c715" datatype="html">
<source>Page title</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/basic/basic.settings.component.ts</context>
<context context-type="linenumber">11</context>
</context-group>
<target>Oldal cím</target>
</trans-unit>
<trans-unit id="0559356d4e98ee90a10ff16250a2bf139eac649b" datatype="html">
<source>Port number. Port 80 is usually what you need.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/basic/basic.settings.component.ts</context>
<context context-type="linenumber">29</context>
</context-group>
<target>Portszám. A 80-as port általában az, amire szükséged van.</target>
</trans-unit>
<trans-unit id="b4b17c583a52ad8b6b15882c46d04ddbd7335816" datatype="html">
<source>Images are loaded from this folder (read permission required)</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/basic/basic.settings.component.ts</context>
<context context-type="linenumber">40</context>
</context-group>
<target>A képeket ebből a mappából tölti be (olvasási engedély szükséges)</target>
</trans-unit>
<trans-unit id="682679bea54c7cdc8fad228e65f4e35d8cf62275" datatype="html">
<source>Page public url</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/basic/basic.settings.component.ts</context>
<context context-type="linenumber">45</context>
</context-group>
<target>Oldal nyilvános urlje (webcím)</target>
</trans-unit>
<trans-unit id="46bb79be15f19c6081f5d139660695902930abbe" datatype="html">
<source>If you access the page form local network its good to know the public url for creating sharing link</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/basic/basic.settings.component.ts</context>
<context context-type="linenumber">51</context>
</context-group>
<target>Ha helyi hálózatról nézed az oldalt, jó ha tudja az oldal a publikus címét, hogy tudjon megosztási linket generálni</target>
</trans-unit>
<trans-unit id="1e99f581a015c671d53abad7c7df6a5ad35bfe85" datatype="html">
<source>Other settings</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">4</context>
</context-group>
<target>Egyéb beállitások</target>
</trans-unit>
<trans-unit id="07807dce2e0dc33743530dd6a8b0d1f24094884d" datatype="html">
<source>Error: </source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">7</context>
</context-group>
<target>Hiba:</target>
</trans-unit>
<trans-unit id="ddf9beb42acb007fe4498e7f7d91fac6737156a5" datatype="html">
<source>Threading</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">11</context>
</context-group>
<target>Háttérszálon futtatás</target>
</trans-unit>
<trans-unit id="c3dec2a9fda84d35b3f44f58e47876f5828d84d8" datatype="html">
<source>Runs directory scanning and thumbnail generation (only for Jimp) in a different thread</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">25</context>
</context-group>
<target>Könyvtrá indexelést és thumnail generálást (csak Jimp esetén) háttérszálon futtatja.</target>
</trans-unit>
<trans-unit id="c29451eea39ce561ed481264df985f6e3b9c39ae" datatype="html">
<source>Scroll based thumbnail
generation</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">30</context>
</context-group>
<target>Scroll-ozás alapú thumbnail
          generálás</target>
</trans-unit>
<trans-unit id="bc8bf5e0d03910950af843d84ada25e3c709b677" datatype="html">
<source>Those thumbnails get higher priority that are visible on the screen</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">45</context>
</context-group>
<target>A képernyőn látható thumnailek nagyobb prioritással generálódnak</target>
</trans-unit>
<trans-unit id="1a693eac5c0c9ee65ea4e8db6e097806141e91f5" datatype="html">
<source>Lazy image rendering</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">50</context>
</context-group>
<target>Lazy kép megjelenítés</target>
</trans-unit>
<trans-unit id="adbdec7eb762da25495914232537db1f7b102d8a" datatype="html">
<source>Shows only the required amount of photos at once. Renders more if page bottom is reached</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">64</context>
</context-group>
<target>Csak a szükséges mennyiségű fotót jeleníti meg egyszerre. újabbakat tölt be, ha elérte az oldal alját</target>
</trans-unit>
<trans-unit id="1fa92c6ce274f878b2625587daa7e08b2a3a8b38" datatype="html">
<source>Cache</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">70</context>
</context-group>
<target>gyorsítótár</target>
</trans-unit>
<trans-unit id="3d5c836021af994d7ecf28083b0595dbd78b9915" datatype="html">
<source>Caches directory contents and search results for better performance</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/other/other.settings.component.ts</context>
<context context-type="linenumber">84</context>
</context-group>
<target>Cach-eli a könyvtár tartalmát és a keresési eredményeket, hogy responzívabb legyen az oldal</target>
</trans-unit>
<trans-unit id="87b1696eb068572c3908643c425ee3090938c1a0" datatype="html">
<source>Folder indexing</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">4</context>
</context-group>
<target>Mappa indexelése</target>
</trans-unit>
<trans-unit id="1be10583851301763cfa3b55d74670808986a583" datatype="html">
<source>Index cache timeout [ms]</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">11</context>
</context-group>
<target>Index cache timeout [ms]</target>
</trans-unit>
<trans-unit id="1dd0f4aff02ce38e0a5935b379b9b28dc2c14a0a" datatype="html">
<source>If there was no indexing in this time, it reindexes. (skipped if indexen in DB and sensitivity is low)</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">19</context>
</context-group>
<target>Ha ennyi ideje nem volt indexelés, újraindexeli a könyvtárat. (kivéve, ha a DB index és az érzékenység alacsony)</target>
</trans-unit>
<trans-unit id="95cda683cfb2041ad808023f29e40d16981b3c5e" datatype="html">
<source>Sub folder preview size</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">23</context>
</context-group>
<target>Alkönyvtár előnézet mérete</target>
</trans-unit>
<trans-unit id="fda1d8005a79f58b5713b5ada5d0eb20321ff640" datatype="html">
<source>Reads this many photos from sub folders</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">31</context>
</context-group>
<target>Ennyi fotót olvas be az alkönytárból</target>
</trans-unit>
<trans-unit id="d0a8aab4720af5526787eec8cfe8dd2e1bf20cac" datatype="html">
<source>Folder reindexing sensitivity</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">36</context>
</context-group>
<target>Folder újra indeyelés érzékenysége</target>
</trans-unit>
<trans-unit id="dc94e5967c3fa68e0bc8fc48250a718cc826a40f" datatype="html">
<source>Set the reindexing sensitivity. High value check the folders for change more often</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">44</context>
</context-group>
<target>Állítsa be az újraindexelés érzékenységét. A magasabb érzékenység gyarkabban ellenőrzi a mappákat válztozás</target>
</trans-unit>
<trans-unit id="b8f78167ef95c21d032b15614e8239cc033a0fd2" datatype="html">
<source>Save
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">51</context>
</context-group>
<target>Mentés</target>
</trans-unit>
<trans-unit id="ae9e824f2eaba4400a5cb66ad946c433dc45b3d5" datatype="html">
<source>Reset
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">54</context>
</context-group>
<target>Visszaállítás</target>
</trans-unit>
<trans-unit id="b0eaa3abce5af3b71c03fe678062333b7b950430" datatype="html">
<source>If you add a new folder to your gallery, the site indexes it automatically.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">60</context>
</context-group>
<target>Ha új mappát ad hozzá a galériához, a webhely automatikusan indexeli.</target>
</trans-unit>
<trans-unit id="2622cf599561bd3154f42feef9ac9960a316a6eb" datatype="html">
<source>If you would like to trigger indexing manually, click index button.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">61</context>
</context-group>
<target>Ha kézzel szeretné indítani az indexelést, kattintson az index gombra.</target>
</trans-unit>
<trans-unit id="9061efbc0c389083e0652206d2b92c8aa68bc722" datatype="html">
<source>Note: search ony searched among the indexed directories</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">62</context>
</context-group>
<target>Megjegyzés: a keresés csak az indexelet mappákban működik</target>
</trans-unit>
<trans-unit id="32cc8ef8dc6f4f239b7f637ac8adaecc55b8e1d8" datatype="html">
<source>Index
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">84</context>
</context-group>
<target>Index</target>
</trans-unit>
<trans-unit id="e7e43ec575247424aa179da55b338fd740e8aa7f" datatype="html">
<source>Cancel
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">89</context>
</context-group>
<target>Mégse</target>
</trans-unit>
<trans-unit id="d68e02eaea0b78b12fceb483b2183a3f5b70d969" datatype="html">
<source>Reset Indexes
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/indexing/indexing.settings.component.ts</context>
<context context-type="linenumber">93</context>
</context-group>
<target>Indexek törlése</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -9,5 +9,13 @@
"exclude": [
"test.ts",
"**/*.spec.ts"
],
"include": [
"./**/*",
"./../node_modules/jw-bootstrap-switch-ng2/dist/index.ts",
"./../node_modules/jw-bootstrap-switch-ng2/dist/directive.ts",
"./../node_modules/ngx-clipboard/src/index.ts",
"./../node_modules/ngx-clipboard/src/clipboard.directive.ts",
"./../node_modules/ngx-clipboard/src/clipboard.service.ts"
]
}

View File

@ -1,6 +1,7 @@
var ts = require('gulp-typescript');
var gulp = require('gulp');
var zip = require('gulp-zip');
var fs = require('fs');
var runSequence = require('run-sequence');
var jsonModify = require('gulp-json-modify');
var exec = require('child_process').exec;
@ -15,12 +16,37 @@ gulp.task('build-backend', function () {
.pipe(gulp.dest("./release"))
});
gulp.task('build-frontend', function (cb) {
exec("ng build -prod --output-path=./release/dist --no-progress", function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
var createFornendTask = function (tpye, script) {
gulp.task(tpye, function (cb) {
exec(script, function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
});
};
gulp.task('build-frontend', function (done) {
var dirCont = fs.readdirSync("./frontend/locale");
var files = dirCont.filter(function (elm) {
return elm.match(/.*\.[a-zA-Z]+\.(xlf)/ig);
});
var languages = files.map(function (f) {
return f.split(".")[1]
});
var tasks = [];
createFornendTask('build-frontend default', "ng build --aot -prod --output-path=./release/dist --no-progress");
tasks.push('build-frontend default');
for (var i = 0; i < files.length; i++) {
createFornendTask('build-frontend ' + languages[i], "ng build --aot -prod --output-path=./release/dist/" + languages[i] + " --no-progress --locale " + languages[i] + " --i18n-format xlf --i18n-file frontend/locale/" + files[i] + " --missing-translation warning");
tasks.push('build-frontend ' + languages[i]);
}
tasks.push(function () {
done();
});
runSequence.apply(this, tasks);
});
gulp.task('copy-static', function () {
@ -56,3 +82,26 @@ gulp.task('build-release', function (done) {
done();
});
});
gulp.task('build-dev', function (done) {
var dirCont = fs.readdirSync("./frontend/locale");
var files = dirCont.filter(function (elm) {
return elm.match(/.*\.[a-zA-Z]+\.(xlf)/ig);
});
var languages = files.map(function (f) {
return f.split(".")[1]
});
var tasks = [];
createFornendTask('build-frontend-dev default', "ng build --prod --output-path=./dist --no-progress");
tasks.push('build-frontend-dev default');
for (var i = 0; i < files.length; i++) {
createFornendTask('build-frontend-dev ' + languages[i], "ng build --prod --output-path=./dist/" + languages[i] + " --no-progress --locale " + languages[i] + " --i18n-format xlf --i18n-file frontend/locale/" + files[i] + " --missing-translation warning");
tasks.push('build-frontend-dev ' + languages[i]);
}
tasks.push(function () {
done();
});
runSequence.apply(this, tasks);
});

View File

@ -15,7 +15,8 @@
"start": "node ./backend/index",
"ng": "ng",
"lint": "ng lint",
"e2e": "ng e2e"
"e2e": "ng e2e",
"build-hu": "ng build --aot --output-path=./dist/hu --locale hu --i18n-format xlf --i18n-file frontend/locale/messages.hu.xlf --missing-translation warning"
},
"repository": {
"type": "git",
@ -27,10 +28,12 @@
"dependencies": {
"bcryptjs": "2.4.3",
"body-parser": "1.18.2",
"cookie-parser": "^1.4.3",
"cookie-session": "2.0.0-beta.3",
"ejs": "2.5.7",
"express": "4.16.2",
"jimp": "0.2.28",
"locale": "^0.1.0",
"mysql": "2.15.0",
"reflect-metadata": "0.1.10",
"sqlite3": "3.1.13",
@ -42,26 +45,26 @@
},
"devDependencies": {
"@agm/core": "^1.0.0-beta.2",
"@angular/animations": "^5.1.1",
"@angular/cli": "1.6.1",
"@angular/common": "~5.1.1",
"@angular/compiler": "~5.1.1",
"@angular/compiler-cli": "^5.1.1",
"@angular/core": "~5.1.1",
"@angular/forms": "~5.1.1",
"@angular/http": "~5.1.1",
"@angular/language-service": "^5.1.1",
"@angular/platform-browser": "~5.1.1",
"@angular/platform-browser-dynamic": "~5.1.1",
"@angular/router": "~5.1.1",
"@angular/animations": "^5.1.2",
"@angular/cli": "1.6.2",
"@angular/common": "~5.1.2",
"@angular/compiler": "~5.1.2",
"@angular/compiler-cli": "^5.1.2",
"@angular/core": "~5.1.2",
"@angular/forms": "~5.1.2",
"@angular/http": "~5.1.2",
"@angular/language-service": "^5.1.2",
"@angular/platform-browser": "~5.1.2",
"@angular/platform-browser-dynamic": "~5.1.2",
"@angular/router": "~5.1.2",
"@types/bcryptjs": "^2.4.1",
"@types/chai": "^4.0.10",
"@types/cookie-session": "^2.0.34",
"@types/express": "^4.0.39",
"@types/express": "^4.11.0",
"@types/gm": "^1.17.33",
"@types/jasmine": "^2.8.2",
"@types/jimp": "^0.2.1",
"@types/node": "^8.5.1",
"@types/jimp": "^0.2.28",
"@types/node": "^8.5.2",
"@types/sharp": "^0.17.6",
"@types/winston": "^2.3.7",
"bootstrap": "^3.3.7",
@ -77,10 +80,10 @@
"intl": "^1.2.5",
"jasmine-core": "^2.8.0",
"jasmine-spec-reporter": "~4.2.1",
"jw-bootstrap-switch-ng2": "^1.0.8",
"karma": "^1.7.1",
"jw-bootstrap-switch-ng2": "1.0.8",
"karma": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-coverage-istanbul-reporter": "^1.3.1",
"karma-jasmine": "^1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.4",
@ -98,9 +101,9 @@
"remap-istanbul": "^0.9.5",
"rimraf": "^2.6.2",
"run-sequence": "^2.2.0",
"rxjs": "^5.5.5",
"rxjs": "^5.5.6",
"ts-helpers": "^1.1.2",
"ts-node": "~4.0.2",
"ts-node": "~4.1.0",
"tslint": "^5.8.0",
"typescript": "^2.6.2",
"zone.js": "^0.8.18"