More translation strings

pull/943/head
Piero Toffanin 2020-12-16 14:37:35 -05:00
rodzic ba3fd861b8
commit 28f35de733
14 zmienionych plików z 91 dodań i 86 usunięć

Wyświetl plik

@ -2,6 +2,7 @@ import React from 'react';
import '../css/AssetDownloadButtons.scss';
import AssetDownloads from '../classes/AssetDownloads';
import PropTypes from 'prop-types';
import { _ } from '../classes/gettext';
class AssetDownloadButtons extends React.Component {
static defaultProps = {
@ -29,7 +30,7 @@ class AssetDownloadButtons extends React.Component {
return (<div className={"asset-download-buttons " + (this.props.showLabel ? "btn-group" : "") + " " + (this.props.direction === "up" ? "dropup" : "")}>
<button type="button" className={"btn btn-sm " + this.props.buttonClass} disabled={this.props.disabled} data-toggle="dropdown">
<i className="glyphicon glyphicon-download"></i>{this.props.showLabel ? " Download Assets" : ""}
<i className="glyphicon glyphicon-download"></i>{this.props.showLabel ? " " + _("Download Assets") : ""}
</button>
{this.props.showLabel ?
<button type="button" className={"btn btn-sm dropdown-toggle " + this.props.buttonClass} data-toggle="dropdown" disabled={this.props.disabled}>

Wyświetl plik

@ -4,8 +4,8 @@ import FormDialog from './FormDialog';
import ProcessingNodeOption from './ProcessingNodeOption';
import PresetUtils from '../classes/PresetUtils';
import PropTypes from 'prop-types';
import $ from 'jquery';
import values from 'object.values';
import { _ } from '../classes/gettext';
if (!Object.values) {
values.shim();
@ -92,13 +92,13 @@ class EditPresetDialog extends React.Component {
show={true}
onShow={this.onShow}
saveIcon="far fa-edit"
title="Edit Task Options"
title={_("Edit Task Options")}
saveAction={this.props.saveAction}
deleteWarning={false}
deleteAction={(this.props.preset.id !== -1 && !this.props.preset.system) ? this.props.deleteAction : undefined}>
{!this.isCustomPreset() ?
<div className="row preset-name">
<label className="col-sm-2 control-label">Name</label>
<label className="col-sm-2 control-label">{_("Name")}</label>
<div className="col-sm-10">
<input type="text" className="form-control" ref={(domNode) => { this.nameInput = domNode; }} value={this.state.name} onChange={this.handleChange('name')} />
</div>

Wyświetl plik

@ -6,6 +6,7 @@ import ErrorMessage from './ErrorMessage';
import PropTypes from 'prop-types';
import Storage from '../classes/Storage';
import $ from 'jquery';
import { _, interpolate } from '../classes/gettext';
class EditTaskForm extends React.Component {
@ -85,7 +86,7 @@ class EditTaskForm extends React.Component {
loadProcessingNodes(){
const failed = () => {
this.setState({error: "Could not load list of processing nodes. Are you connected to the internet?"});
this.setState({error: _("Could not load list of processing nodes. Are you connected to the internet?")});
}
this.nodesRequest =
@ -93,11 +94,8 @@ class EditTaskForm extends React.Component {
if (Array.isArray(json)){
// No nodes with options?
const noProcessingNodesError = (nodes) => {
var extra = nodes ? "We tried to reach:<ul>" + nodes.map(n => Utils.html`<li><a href="${n.url}">${n.label}</a></li>`).join("") + "</ul>" : "";
this.setState({error: `There are no usable processing nodes. ${extra}Make sure that at least one processing node is reachable and
that you have granted the current user sufficient permissions to view
the processing node (by going to Administration -- Processing Nodes -- Select Node -- Object Permissions -- Add User/Group and check CAN VIEW PROCESSING NODE).
If you are bringing a node back online, it will take about 30 seconds for WebODM to recognize it.`});
var extra = nodes ? _("We tried to reach:") + "<ul>" + nodes.map(n => Utils.html`<li><a href="${n.url}">${n.label}</a></li>`).join("") + "</ul>" : "";
this.setState({error: _("There are no usable processing nodes.") + extra + _("Make sure that at least one processing node is reachable and that you have granted the current user sufficient permissions to view the processing node (by going to Administration -- Processing Nodes -- Select Node -- Object Permissions -- Add User/Group and check CAN VIEW PROCESSING NODE). If you are bringing a node back online, it will take about 30 seconds for WebODM to recognize it.")});
};
if (json.length === 0){
@ -215,7 +213,7 @@ class EditTaskForm extends React.Component {
loadPresets(){
const failed = () => {
this.setState({error: "Could not load list of presets. Are you connected to the internet?"});
this.setState({error: _("Could not load list of presets. Are you connected to the internet?")});
}
this.presetsRequest =
@ -224,13 +222,14 @@ class EditTaskForm extends React.Component {
// Add custom preset
const customPreset = {
id: -1,
name: "(Custom)",
name: "(" + _("Custom") + ")",
options: [],
system: true
};
presets.unshift(customPreset);
// Choose preset
_("Default"); // Add translation
let selectedPreset = presets[0],
defaultPreset = presets.find(p => p.name === "Default"); // Do not translate Default
if (defaultPreset) selectedPreset = defaultPreset;
@ -351,7 +350,7 @@ class EditTaskForm extends React.Component {
getAvailableOptionsOnlyText(options, availableOptions){
const opts = this.getAvailableOptionsOnly(options, availableOptions);
let res = opts.map(opt => `${opt.name}:${opt.value}`).join(", ");
if (!res) res = "Default";
if (!res) res = _("Default");
return res;
}
@ -382,7 +381,7 @@ class EditTaskForm extends React.Component {
if (!customPreset){
customPreset = {
id: -1,
name: "(Custom)",
name: "(" + _("Custom") + ")",
options: [],
system: true
};
@ -435,7 +434,7 @@ class EditTaskForm extends React.Component {
this.setState({presetActionPerforming: true});
const isCustom = selectedPreset.id === -1,
name = isCustom ? "My Preset" : "Copy of " + selectedPreset.name;
name = isCustom ? _("My Preset") : interpolate(_("Copy of %(preset)s"), {preset: selectedPreset.name});
$.ajax({
url: `/api/presets/`,
@ -458,7 +457,7 @@ class EditTaskForm extends React.Component {
this.setState({presets, selectedPreset: preset});
this.handleEditPreset();
}).fail(() => {
this.setState({presetError: "Could not duplicate the preset. Please try to refresh the page."});
this.setState({presetError: _("Could not duplicate the preset. Please try to refresh the page.")});
}).always(() => {
this.setState({presetActionPerforming: false});
});
@ -467,11 +466,11 @@ class EditTaskForm extends React.Component {
handleDeletePreset(){
const { selectedPreset, presets } = this.state;
if (selectedPreset.system){
this.setState({presetError: "System presets can only be removed by a staff member from the Administration panel."});
this.setState({presetError: _("System presets can only be removed by a staff member from the Administration panel.")});
return;
}
if (window.confirm(`Are you sure you want to delete "${selectedPreset.name}"?`)){
if (window.confirm(interpolate(_('Are you sure you want to delete "%(preset)s"?'), { preset: selectedPreset.name}))){
this.setState({presetActionPerforming: true});
return $.ajax({
@ -484,7 +483,7 @@ class EditTaskForm extends React.Component {
// Select first by default
this.setState({presets, selectedPreset: presets[0], editingPreset: false});
}).fail(() => {
this.setState({presetError: "Could not delete the preset. Please try to refresh the page."});
this.setState({presetError: _("Could not delete the preset. Please try to refresh the page.")});
}).always(() => {
this.setState({presetActionPerforming: false});
});
@ -499,7 +498,7 @@ class EditTaskForm extends React.Component {
<div className="alert alert-warning">
<div dangerouslySetInnerHTML={{__html:this.state.error}}></div>
<button className="btn btn-sm btn-primary" onClick={this.retryLoad}>
<i className="fa fa-rotate-left"></i> Retry
<i className="fa fa-rotate-left"></i> {_("Retry")}
</button>
</div>
</div>);
@ -515,35 +514,35 @@ class EditTaskForm extends React.Component {
value={this.state.selectedPreset.id}
onChange={this.handleSelectPreset}>
{this.state.presets.map(preset =>
<option value={preset.id} key={preset.id} className={preset.system ? "system-preset" : ""}>{preset.name}</option>
<option value={preset.id} key={preset.id} className={preset.system ? "system-preset" : ""}>{preset.name === "Default" ? _(preset.name) : preset.name}</option>
)}
</select>
{!this.state.presetActionPerforming ?
<div className="btn-group presets-dropdown">
<button type="button" className="btn btn-default" title="Edit Task Options" onClick={this.handleEditPreset}>
<i className="fa fa-sliders-h"></i> Edit
<button type="button" className="btn btn-default" title={_("Edit Task Options")} onClick={this.handleEditPreset}>
<i className="fa fa-sliders-h"></i> {_("Edit")}
</button>
<button type="button" className="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span className="caret"></span>
</button>
<ul className="dropdown-menu">
<li>
<a href="javascript:void(0);" onClick={this.handleEditPreset}><i className="fa fa-sliders-h"></i> Edit</a>
<a href="javascript:void(0);" onClick={this.handleEditPreset}><i className="fa fa-sliders-h"></i> {_("Edit")}</a>
</li>
<li className="divider"></li>
{this.state.selectedPreset.id !== -1 ?
<li>
<a href="javascript:void(0);" onClick={this.handleDuplicateSavePreset}><i className="fa fa-copy"></i> Duplicate</a>
<a href="javascript:void(0);" onClick={this.handleDuplicateSavePreset}><i className="fa fa-copy"></i> {_("Duplicate")}</a>
</li>
:
<li>
<a href="javascript:void(0);" onClick={this.handleDuplicateSavePreset}><i className="fa fa-save"></i> Save</a>
<a href="javascript:void(0);" onClick={this.handleDuplicateSavePreset}><i className="fa fa-save"></i> {_("Save")}</a>
</li>
}
<li className={this.state.selectedPreset.system ? "disabled" : ""}>
<a href="javascript:void(0);" onClick={this.handleDeletePreset}><i className="fa fa-trash"></i> Delete</a>
<a href="javascript:void(0);" onClick={this.handleDeletePreset}><i className="fa fa-trash"></i> {_("Delete")}</a>
</li>
</ul>
</div>
@ -554,7 +553,7 @@ class EditTaskForm extends React.Component {
taskOptions = (
<div>
<div className="form-group">
<label className="col-sm-2 control-label">Processing Node</label>
<label className="col-sm-2 control-label">{_("Processing Node")}</label>
<div className="col-sm-10">
<select className="form-control" value={this.state.selectedNode.key} onChange={this.handleSelectNode}>
{this.state.processingNodes.map(node =>
@ -564,7 +563,7 @@ class EditTaskForm extends React.Component {
</div>
</div>
<div className="form-group form-inline">
<label className="col-sm-2 control-label">Options</label>
<label className="col-sm-2 control-label">{_("Options")}</label>
<div className="col-sm-10">
{!this.props.inReview ? optionsSelector :
<div className="review-options">
@ -588,14 +587,14 @@ class EditTaskForm extends React.Component {
);
}else{
taskOptions = (<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">Loading processing nodes and presets... <i className="fa fa-sync fa-spin fa-fw"></i></div>
<div className="col-sm-offset-2 col-sm-10">{_("Loading processing nodes and presets...")} <i className="fa fa-sync fa-spin fa-fw"></i></div>
</div>);
}
return (
<div className="edit-task-form">
<div className="form-group">
<label className="col-sm-2 control-label">Name</label>
<label className="col-sm-2 control-label">{_("Name")}</label>
<div className="col-sm-10">
{this.state.loadingTaskName ?
<i className="fa fa-circle-notch fa-spin fa-fw name-loading"></i>

Wyświetl plik

@ -25,7 +25,7 @@ class ErrorMessage extends React.Component {
if (parent.state[prop]){
return (
<div className={"alert alert-warning alert-dismissible " + (this.props.className ? this.props.className : "")}>
<button type="button" className="close" aria-label="Close" onClick={this.close}><span aria-hidden="true">&times;</span></button>
<button type="button" className="close" title={_("Close")} onClick={this.close}><span aria-hidden="true">&times;</span></button>
{parent.state[prop]}
</div>
);

Wyświetl plik

@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import '../css/Histogram.scss';
import d3 from 'd3';
import { _ } from '../classes/gettext';
export default class Histogram extends React.Component {
static defaultProps = {
@ -289,8 +290,8 @@ export default class Histogram extends React.Component {
return (<div className={"histogram " + (this.props.loading ? "disabled" : "")}>
<div ref={(domNode) => { this.hgContainer = domNode; }}>
</div>
<label>Min:</label> <input onChange={this.handleChangeMin} type="number" className="form-control min-max" size={5} value={this.state.min} />
<label>Max:</label> <input onChange={this.handleChangeMax} type="number" className="form-control min-max" size={5} value={this.state.max} />
<label>{_("Min:")}</label> <input onChange={this.handleChangeMin} type="number" className="form-control min-max" size={5} value={this.state.min} />
<label>{_("Max:")}</label> <input onChange={this.handleChangeMax} type="number" className="form-control min-max" size={5} value={this.state.max} />
</div>);
}
}

Wyświetl plik

@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import AssetDownloads from '../classes/AssetDownloads';
import '../css/ImagePopup.scss';
import { _ } from '../classes/gettext';
class ImagePopup extends React.Component {
static propTypes = {
@ -43,7 +44,7 @@ class ImagePopup extends React.Component {
}
imageOnError = () => {
this.setState({error: "Image is missing", loading: false});
this.setState({error: _("Image is missing"), loading: false});
}
imageOnLoad = () => {
@ -82,7 +83,7 @@ class ImagePopup extends React.Component {
<a onClick={this.onImgClick} href="javascript:void(0);" title={feature.properties.filename}><img style={{borderRadius: "4px"}} src={imageUrl} onLoad={this.imageOnLoad} onError={this.imageOnError} /></a>
</div>,
<div key="download-image">
<a href={downloadImageLink}><i className="fa fa-image"></i> Download Image</a>
<a href={downloadImageLink}><i className="fa fa-image"></i> {_("Download Image")}</a>
</div>
]}
<div>

Wyświetl plik

@ -5,6 +5,8 @@ import Dropzone from '../vendor/dropzone';
import csrf from '../django/csrf';
import ErrorMessage from './ErrorMessage';
import UploadProgressBar from './UploadProgressBar';
import { _, interpolate } from '../classes/gettext';
import Trans from './Trans';
class ImportTaskPanel extends React.Component {
static defaultProps = {
@ -58,7 +60,7 @@ class ImportTaskPanel extends React.Component {
});
this.dz.on("error", (file) => {
if (this.state.uploading) this.setState({error: "Cannot upload file. Check your internet connection and try again."});
if (this.state.uploading) this.setState({error: _("Cannot upload file. Check your internet connection and try again.")});
})
.on("sending", () => {
this.setState({typeUrl: false, uploading: true, totalCount: 1});
@ -86,10 +88,10 @@ class ImportTaskPanel extends React.Component {
if (!response.id) throw new Error(`Expected id field, but none given (${response})`);
this.props.onImported();
}catch(e){
this.setState({error: `Invalid response from server: ${e.message}`});
this.setState({error: interpolate(_('Invalid response from server: %(error)s'), { error: e.message})});
}
}else if (this.state.uploading){
this.setState({uploading: false, error: "An error occured while uploading the file. Please try again."});
this.setState({uploading: false, error: _("An error occured while uploading the file. Please try again.")});
}
});
}
@ -133,11 +135,11 @@ class ImportTaskPanel extends React.Component {
if (json.id){
this.props.onImported();
}else{
this.setState({error: json.error || `Cannot import from URL, server responded: ${JSON.stringify(json)}`});
this.setState({error: json.error || interpolate(_("Invalid JSON response: %(error)s"), {error: JSON.stringify(json)})});
}
})
.fail(() => {
this.setState({importingFromUrl: false, error: "Cannot import from URL. Check your internet connection."});
this.setState({importingFromUrl: false, error: _("Cannot import from URL. Check your internet connection.")});
});
}
@ -153,16 +155,16 @@ class ImportTaskPanel extends React.Component {
<div className="form-horizontal">
<ErrorMessage bind={[this, 'error']} />
<button type="button" className="close theme-color-primary" aria-label="Close" onClick={this.cancel}><span aria-hidden="true">&times;</span></button>
<h4>Import Existing Assets</h4>
<p>You can import .zip files that have been exported from existing tasks via Download Assets <i className="glyphicon glyphicon-arrow-right"></i> All Assets.</p>
<button type="button" className="close theme-color-primary" title="Close" onClick={this.cancel}><span aria-hidden="true">&times;</span></button>
<h4>{_("Import Existing Assets")}</h4>
<p><Trans params={{arrow: '<i class="glyphicon glyphicon-arrow-right"></i>'}}>{_("You can import .zip files that have been exported from existing tasks via Download Assets %(arrow)s All Assets.")}</Trans></p>
<button disabled={this.state.uploading}
type="button"
className="btn btn-primary"
ref={this.setRef("uploadButton")}>
<i className="glyphicon glyphicon-upload"></i>
Upload a File
{_("Upload a File")}
</button>
<button disabled={this.state.uploading}
type="button"
@ -170,7 +172,7 @@ class ImportTaskPanel extends React.Component {
onClick={this.handleImportFromUrl}
ref={this.setRef("importFromUrlButton")}>
<i className="glyphicon glyphicon-cloud-download"></i>
Import From URL
{_("Import From URL")}
</button>
{this.state.typeUrl ?
@ -179,7 +181,7 @@ class ImportTaskPanel extends React.Component {
<input disabled={this.state.importingFromUrl} onChange={this.handleChangeImportUrl} size="45" type="text" className="form-control" placeholder="http://" value={this.state.importUrl} />
<button onClick={this.handleConfirmImportUrl}
disabled={this.state.importUrl.length < 4 || this.state.importingFromUrl}
className="btn-import btn btn-primary"><i className="glyphicon glyphicon-cloud-download"></i> Import</button>
className="btn-import btn btn-primary"><i className="glyphicon glyphicon-cloud-download"></i> {_("Import")}</button>
</div>
</div> : ""}
@ -189,7 +191,7 @@ class ImportTaskPanel extends React.Component {
className="btn btn-danger btn-sm"
onClick={this.cancelUpload}>
<i className="glyphicon glyphicon-remove-circle"></i>
Cancel Upload
{_("Cancel Upload")}
</button>
</div> : ""}
</div>

Wyświetl plik

@ -7,6 +7,7 @@ import Utils from '../classes/Utils';
import Workers from '../classes/Workers';
import ErrorMessage from './ErrorMessage';
import $ from 'jquery';
import { _, interpolate } from '../classes/gettext';
export default class LayersControlLayer extends React.Component {
static defaultProps = {
@ -245,7 +246,7 @@ export default class LayersControlLayer extends React.Component {
}else if (result.error){
this.setState({exportLoading: false, error: result.error});
}else{
this.setState({exportLoading: false, error: "Invalid response: " + result});
this.setState({exportLoading: false, error: interpolate(_("Invalid JSON response: %(error)s"), {error: JSON.stringify(result)})});
}
}).fail(error => {
this.setState({exportLoading: false, error: JSON.stringify(error)});
@ -283,7 +284,7 @@ export default class LayersControlLayer extends React.Component {
{formula !== "" && algorithms ?
<div className="row form-group form-inline">
<label className="col-sm-3 control-label">Algorithm:</label>
<label className="col-sm-3 control-label">{_("Algorithm:")}</label>
<div className="col-sm-9 ">
{histogramLoading ?
<i className="fa fa-circle-notch fa-spin fa-fw" /> :
@ -295,7 +296,7 @@ export default class LayersControlLayer extends React.Component {
{bands !== "" && algo ?
<div className="row form-group form-inline">
<label className="col-sm-3 control-label">Filter:</label>
<label className="col-sm-3 control-label">{_("Filter:")}</label>
<div className="col-sm-9 ">
{histogramLoading ?
<i className="fa fa-circle-notch fa-spin fa-fw" /> :
@ -307,7 +308,7 @@ export default class LayersControlLayer extends React.Component {
{colorMap && color_maps.length ?
<div className="row form-group form-inline">
<label className="col-sm-3 control-label">Color:</label>
<label className="col-sm-3 control-label">{_("Color:")}</label>
<div className="col-sm-9 ">
{histogramLoading ?
<i className="fa fa-circle-notch fa-spin fa-fw" /> :
@ -319,18 +320,18 @@ export default class LayersControlLayer extends React.Component {
{hillshade !== "" ?
<div className="row form-group form-inline">
<label className="col-sm-3 control-label">Shading:</label>
<label className="col-sm-3 control-label">{_("Shading:")}</label>
<div className="col-sm-9 ">
<select className="form-control" value={hillshade} onChange={this.handleSelectHillshade}>
<option value="0">None</option>
<option value="6">Normal</option>
<option value="18">Extruded</option>
<option value="0">{_("None")}</option>
<option value="6">{_("Normal")}</option>
<option value="18">{_("Extruded")}</option>
</select>
</div>
</div> : ""}
<div className="row form-group form-inline">
<label className="col-sm-3 control-label">Export: </label>
<label className="col-sm-3 control-label">{_("Export:")} </label>
<div className="col-sm-9">
<button onClick={this.handleExport} disabled={exportLoading} type="button" className="btn btn-sm btn-default">
{exportLoading ? <i className="fa fa-spin fa-circle-notch"/> : <i className="far fa-image fa-fw" />} GeoTIFF

Wyświetl plik

@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import '../css/LayersControlPanel.scss';
import LayersControlLayer from './LayersControlLayer';
import { _ } from '../classes/gettext';
export default class LayersControlPanel extends React.Component {
static defaultProps = {
@ -22,7 +23,7 @@ export default class LayersControlPanel extends React.Component {
render(){
let content = "";
if (!this.props.layers.length) content = (<span><i className="loading fa fa-circle-notch fa-spin"></i> Loading...</span>);
if (!this.props.layers.length) content = (<span><i className="loading fa fa-circle-notch fa-spin"></i> {_("Loading...")}</span>);
else{
content = (<div>
{this.props.overlays.length ?
@ -40,7 +41,7 @@ export default class LayersControlPanel extends React.Component {
return (<div className="layers-control-panel">
<span className="close-button" onClick={this.props.onClose}/>
<div className="title">Layers</div>
<div className="title">{_("Layers")}</div>
<hr/>
{content}
</div>);

Wyświetl plik

@ -26,6 +26,7 @@ import update from 'immutability-helper';
import Utils from '../classes/Utils';
import '../vendor/leaflet/Leaflet.Ajax';
import '../vendor/leaflet/Leaflet.Awesome-markers';
import { _ } from '../classes/gettext';
class Map extends React.Component {
static defaultProps = {
@ -78,13 +79,13 @@ class Map extends React.Component {
typeToHuman = (type) => {
switch(type){
case "orthophoto":
return "Orthophoto";
return _("Orthophoto");
case "plant":
return "Plant Health";
return _("Plant Health");
case "dsm":
return "DSM";
return _("DSM");
case "dtm":
return "DTM";
return _("DTM");
}
return "";
}
@ -255,7 +256,7 @@ class Map extends React.Component {
}
}
});
shotsLayer[Symbol.for("meta")] = {name: name + " (Cameras)", icon: "fa fa-camera fa-fw"};
shotsLayer[Symbol.for("meta")] = {name: name + " " + _("(Cameras)"), icon: "fa fa-camera fa-fw"};
this.setState(update(this.state, {
overlays: {$push: [shotsLayer]}
@ -327,13 +328,12 @@ class Map extends React.Component {
const customLayer = L.layerGroup();
customLayer.on("add", a => {
let url = window.prompt(`Enter a tile URL template. Valid tokens are:
{z}, {x}, {y} for Z/X/Y tile scheme
{-y} for flipped TMS-style Y coordinates
Example:
https://a.tile.openstreetmap.org/{z}/{x}/{y}.png
`, 'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png');
let url = window.prompt([_('Enter a tile URL template. Valid coordinates are:'),
_('{z}, {x}, {y} for Z/X/Y tile scheme'),
_('{-y} for flipped TMS-style Y coordinates'),
'',
_('Example:'),
'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'].join("\n"), 'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png');
if (url){
customLayer.clearLayers();
@ -346,8 +346,8 @@ https://a.tile.openstreetmap.org/{z}/{x}/{y}.png
l.bringToBack();
}
});
this.basemaps["Custom"] = customLayer;
this.basemaps["None"] = L.layerGroup();
this.basemaps[_("Custom")] = customLayer;
this.basemaps[_("None")] = L.layerGroup();
}
this.layersControl = new LayersControl({
@ -398,7 +398,7 @@ https://a.tile.openstreetmap.org/{z}/{x}/{y}.png
this.container = Leaflet.DomUtil.create('div', 'leaflet-control-add-overlay leaflet-bar leaflet-control');
Leaflet.DomEvent.disableClickPropagation(this.container);
const btn = Leaflet.DomUtil.create('a', 'leaflet-control-add-overlay-button');
btn.setAttribute("title", "Add a temporary GeoJSON (.json) or ShapeFile (.zip) overlay");
btn.setAttribute("title", _("Add a temporary GeoJSON (.json) or ShapeFile (.zip) overlay"));
this.container.append(btn);
addDnDZone(btn, {url: "/", clickable: true});
@ -447,7 +447,7 @@ https://a.tile.openstreetmap.org/{z}/{x}/{y}.png
$assetLinks.append($(linksHtml));
})
.fail(() => {
$assetLinks.append($("<li>Error: cannot load assets list. </li>"));
$assetLinks.append($("<li>" + _("Error: cannot load assets list.") + "</li>"));
})
.always(() => {
$assetLinks.removeClass('loading');

Wyświetl plik

@ -540,7 +540,7 @@ class ProjectListItem extends React.Component {
{this.state.upload.error !== "" ?
<div className="alert alert-warning alert-dismissible">
<button type="button" className="close" aria-label={_("Close")} onClick={this.closeUploadError}><span aria-hidden="true">&times;</span></button>
<button type="button" className="close" title={_("Close")} onClick={this.closeUploadError}><span aria-hidden="true">&times;</span></button>
{this.state.upload.error}
</div>
: ""}

Wyświetl plik

@ -222,7 +222,7 @@ class TaskListItem extends React.Component {
optionsToList(options){
if (!Array.isArray(options)) return "";
else if (options.length === 0) return _("Default");
else if (options.length === 0) return "Default";
else {
return options.map(opt => `${opt.name}: ${opt.value}`).join(", ");
}
@ -531,9 +531,7 @@ class TaskListItem extends React.Component {
{showExitedWithCodeOneHints ?
<div className="task-warning"><i className="fa fa-info-circle"></i> <div className="inline">
"Process exited with code 1" means that part of the processing failed. Sometimes it's a problem with the dataset, sometimes it can be solved by tweaking the Task Options and sometimes it might be a bug!
If you need help, upload your images somewhere like <a href="https://www.dronedb.app/" target="_blank">DroneDB</a> or <a href="https://drive.google.com/drive/u/0/" target="_blank">Google Drive</a> and <a href="http://community.opendronemap.org/c/webodm" target="_blank">open a topic</a> on our community forum, making
sure to include a <a href="javascript:void(0);" onClick={this.setView("console")}>copy of your task's output</a>. Our awesome contributors will try to help you! <i className="far fa-smile"></i>
<Trans params={{link1: `<a href="https://www.dronedb.app/" target="_blank">DroneDB</a>`, link2: `<a href="https://drive.google.com/drive/u/0/" target="_blank">Google Drive</a>`, open_a_topic: `<a href="http://community.opendronemap.org/c/webodm" target="_blank">${_("open a topic")}</a>`, }}>{_("\"Process exited with code 1\" means that part of the processing failed. Sometimes it's a problem with the dataset, sometimes it can be solved by tweaking the Task Options and sometimes it might be a bug! If you need help, upload your images somewhere like %(link1)s or %(link2)s and %(open_a_topic)s on our community forum, making sure to include a copy of your task's output. Our awesome contributors will try to help you!")}</Trans> <i className="far fa-smile"></i>
</div>
</div>
: ""}
@ -579,12 +577,12 @@ class TaskListItem extends React.Component {
if (task.last_error){
statusLabel = getStatusLabel(task.last_error, 'error');
}else if (!task.processing_node && !imported){
statusLabel = getStatusLabel("Set a processing node");
statusLabel = getStatusLabel(_("Set a processing node"));
statusIcon = "fa fa-hourglass-3";
showEditLink = true;
}else if (task.partial && !task.pending_action){
statusIcon = "fa fa-hourglass-3";
statusLabel = getStatusLabel("Waiting for image upload...");
statusLabel = getStatusLabel(_("Waiting for image upload..."));
}else{
let progress = 100;
let type = 'done';

Wyświetl plik

@ -15,7 +15,8 @@ class Trans extends React.Component {
if (!this.props.children) return (<span/>);
let content = "";
console.log(this.props.children);
console.log(interpolate(this.props.children, this.props.params));
if (typeof this.props.children === "string"){
content = (<span dangerouslySetInnerHTML={{__html: interpolate(this.props.children, this.props.params)}}></span>);
}else{
@ -31,7 +32,7 @@ class Trans extends React.Component {
i++;
});
}
console.log(content);
return content;
}
}

Wyświetl plik

@ -34,7 +34,7 @@
<li>{% trans 'You need at least 5 images' %}</li>
<li>{% trans 'Images must overlap by 65% or more' %}</li>
<li>{% trans 'For great 3D, images must overlap by 83%' %}</li>
<li>{% trans 'A <a href="https://github.com/OpenDroneMap/OpenDroneMap/wiki/Running-OpenDroneMap#running-odm-with-ground-control" target="_blank">GCP file</a> is optional, but can increase georeferencing accuracy' %}</li>
<li>{% blocktrans with link_start='<a href="https://github.com/OpenDroneMap/OpenDroneMap/wiki/Running-OpenDroneMap#running-odm-with-ground-control" target="_blank">' link_end='</a>' %}A {{link_start}}GCP File{{link_end}} is optional, but can increase georeferencing accuracy{% endblocktrans %}</li>
</ul>
</p>
{% endif %}