This commit is contained in:
Ian Wagner
2024-09-02 21:23:13 +09:00
committed by GitHub
10 changed files with 88 additions and 15 deletions

View File

@@ -72,6 +72,16 @@ npm run lint-css
npm run sort-styles
```
Update the translation files (run this whenever touching user-facing strings).
After running, check your working copy for files and add/correct as needed.
```
npm run i18n:refresh
```
You can test the UI in different languages using the dropdown in the top menu
(Maputnik does not automatically localize based on browser language settings
at the moment).
## Tests
For E2E testing we use [Cypress](https://www.cypress.io/)

View File

@@ -160,6 +160,18 @@ describe("modals", () => {
).shouldInclude({ "maputnik:thunderforest_access_token": apiKey });
});
it("stadia access token", () => {
let apiKey = "testing123";
when.setValue(
"modal:settings.maputnik:stadia_access_token",
apiKey
);
when.click("modal:settings.name");
then(
get.styleFromLocalStorage().then((style) => style.metadata)
).shouldInclude({ "maputnik:stadia_access_token": apiKey });
});
it("style renderer", () => {
cy.on("uncaught:exception", () => false); // this is due to the fact that this is an invalid style for openlayers
when.select("modal:settings.maputnik:renderer", "ol");

View File

@@ -18,14 +18,15 @@ type DocProps = {
'sdk-support'?: {
[key: string]: typeof headers
}
docUrl?: string
}
};
}; // & WithTranslation?
export default class Doc extends React.Component<DocProps> {
render () {
const {fieldSpec} = this.props;
const {doc, values} = fieldSpec;
const {doc, values, docUrl} = fieldSpec;
const sdkSupport = fieldSpec['sdk-support'];
const renderValues = (
@@ -85,7 +86,12 @@ export default class Doc extends React.Component<DocProps> {
</table>
</div>
}
{docUrl &&
<div className="SpecDoc__learn-more">
<a href={docUrl} target="_blank" rel="noreferrer" onClick={() => console.log('Link clicked')}>Learn More (TODO i18n)</a>
</div>
}
</>
);
}
}
}

View File

@@ -130,6 +130,12 @@ class ModalExportInternal extends React.Component<ModalExportInternalProps> {
value={(this.props.mapStyle.metadata || {} as any)['maputnik:thunderforest_access_token']}
onChange={this.changeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
/>
<FieldString
label={fsa.maputnik.stadia_access_token.label}
fieldSpec={fsa.maputnik.stadia_access_token}
value={(this.props.mapStyle.metadata || {} as any)['maputnik:stadia_access_token']}
onChange={this.changeMetadataProperty.bind(this, "maputnik:stadia_access_token")}
/>
</div>
<div className="maputnik-modal-export-buttons">

View File

@@ -156,6 +156,14 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
onChange={onChangeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
/>
<FieldString
label={fsa.maputnik.stadia_access_token.label}
fieldSpec={fsa.maputnik.stadia_access_token}
data-wd-key="modal:settings.maputnik:stadia_access_token"
value={metadata['maputnik:stadia_access_token']}
onChange={onChangeMetadataProperty.bind(this, "maputnik:stadia_access_token")}
/>
<FieldArray
label={t("Center")}
fieldSpec={latest.$root.center}

View File

@@ -4,15 +4,22 @@ const spec = (t: TFunction) => ({
maputnik: {
maptiler_access_token: {
label: t("MapTiler Access Token"),
doc: t("Public access token for MapTiler Cloud.")
doc: t("Public access token for MapTiler Cloud."),
docUrl: "https://docs.maptiler.com/cloud/api/authentication-key/"
},
thunderforest_access_token: {
label: t("Thunderforest Access Token"),
doc: t("Public access token for Thunderforest services.")
doc: t("Public access token for Thunderforest services."),
docUrl: "https://www.thunderforest.com/docs/apikeys/",
},
stadia_access_token: {
label: t("Stadia Maps API Key"),
doc: t("API key for Stadia Maps."),
docUrl: "https://docs.stadiamaps.com/authentication/",
},
style_renderer: {
label: t("Style Renderer"),
doc: t("Choose the default Maputnik renderer for this style."),
doc: t("Choose the default Maputnik renderer for this style.")
},
}
})

View File

@@ -55,10 +55,6 @@ function indexOfLayer(layers: LayerSpecification[], layerId: string) {
}
function getAccessToken(sourceName: string, mapStyle: StyleSpecification, opts: {allowFallback?: boolean}) {
if(sourceName === "thunderforest_transport" || sourceName === "thunderforest_outdoors") {
sourceName = "thunderforest"
}
const metadata = mapStyle.metadata || {} as any;
let accessToken = metadata[`maputnik:${sourceName}_access_token`]
@@ -74,18 +70,38 @@ function replaceSourceAccessToken(mapStyle: StyleSpecification, sourceName: stri
if(!source) return mapStyle
if(!("url" in source) || !source.url) return mapStyle
const accessToken = getAccessToken(sourceName, mapStyle, opts)
let authSourceName = sourceName
if(sourceName === "thunderforest_transport" || sourceName === "thunderforest_outdoors") {
authSourceName = "thunderforest"
}
else if (("url" in source) && source.url?.match(/\.stadiamaps\.com/)) {
// The code currently usually assumes openmaptiles == MapTiler,
// so we need to check the source URL.
authSourceName = "stadia"
}
const accessToken = getAccessToken(authSourceName, mapStyle, opts)
if(!accessToken) {
// Early exit.
return mapStyle;
}
let sourceUrl: string
if (authSourceName == "stadia") {
// Stadia Maps does not always require an API key,
// so there is no placeholder in our styles.
// We append it at the end of the URL when exporting if necessary.
sourceUrl = `${source.url}?api_key=${accessToken}`
} else {
sourceUrl = source.url.replace('{key}', accessToken)
}
const changedSources = {
...mapStyle.sources,
[sourceName]: {
...source,
url: source.url.replace('{key}', accessToken)
url: sourceUrl
}
}
const changedStyle = {
@@ -120,6 +136,8 @@ function stripAccessTokens(mapStyle: StyleSpecification) {
...mapStyle.metadata as any
};
delete changedMetadata['maputnik:openmaptiles_access_token'];
delete changedMetadata['maputnik:thunderforest_access_token'];
delete changedMetadata['maputnik:stadia_access_token'];
return {
...mapStyle,
metadata: changedMetadata

View File

@@ -82,7 +82,7 @@
"Close modal": "סגירת חלונית",
"Debug": "דיבאג",
"Options": "אפשרויות",
"<0>Open in OSM</0> &mdash; Opens the current view on openstreetmap.org": "<0>פתיחה ב-OSM</0> - פתיחה של התצוגה הנוכחית ב- openstreetmap.org",
"<0>Open in OSM</0> Opens the current view on openstreetmap.org": "<0>פתיחה ב-OSM</0> - פתיחה של התצוגה הנוכחית ב- openstreetmap.org",
"Export Style": "ייצוא של הסטייל",
"Download Style": "הורדה של הסטייל",
"Download a JSON style to your computer.": "הורדה של הסטייל למחשב",
@@ -179,6 +179,8 @@
"Public access token for MapTiler Cloud.": "Public access token for MapTiler Cloud.",
"Thunderforest Access Token": "Thunderforest Access Token",
"Public access token for Thunderforest services.": "Public access token for Thunderforest services.",
"Stadia Maps API Key": "Stadia Maps API Key",
"API key for Stadia Maps.": "API key for Stadia Maps",
"Style Renderer": "צייר הסטייל",
"Choose the default Maputnik renderer for this style.": "בחירת צייר ברירת המחדל של מפוטניק עבור הסטייל הזה"
}

View File

@@ -82,7 +82,7 @@
"Close modal": "モーダルを閉じる",
"Debug": "デバッグ",
"Options": "設定",
"<0>Open in OSM</0> &mdash; Opens the current view on openstreetmap.org": "現在のビューを <0>openstreetmap.org で開く</0>",
"<0>Open in OSM</0> Opens the current view on openstreetmap.org": "現在のビューを <0>openstreetmap.org で開く</0>",
"Export Style": "スタイルをエクスポート",
"Download Style": "スタイルをダウンロード",
"Download a JSON style to your computer.": "パソコンにJSONスタイルをダウンロードします。",
@@ -179,6 +179,8 @@
"Public access token for MapTiler Cloud.": "MapTiler Cloud の公開用アクセストークン",
"Thunderforest Access Token": "Thunderforest アクセストークン",
"Public access token for Thunderforest services.": "Thunderforest サービスの公開用アクセストークン",
"Stadia Maps API Key": "Stadia Maps API キー",
"API key for Stadia Maps.": "Stadia Maps の API キー",
"Style Renderer": "スタイルレンダラ",
"Choose the default Maputnik renderer for this style.": "このスタイルのデフォルトの Maputnik レンダラを選択してください",
"Layer options": "レイヤー設定",

View File

@@ -82,7 +82,6 @@
"Close modal": "关闭模态框",
"Debug": "调试",
"Options": "选项",
"<0>Open in OSM</0> — Opens the current view on openstreetmap.org": "在 openstreetmap.org 打开当前视图",
"Export Style": "导出样式",
"Download Style": "下载样式",
"Download a JSON style to your computer.": "将JSON样式下载到您的电脑。",
@@ -179,8 +178,11 @@
"Public access token for MapTiler Cloud.": "MapTiler Cloud 的公共访问令牌。",
"Thunderforest Access Token": "Thunderforest 访问令牌",
"Public access token for Thunderforest services.": "Thunderforest 服务的公共访问令牌。",
"Stadia Maps API Key": "Stadia Maps API 密钥",
"API key for Stadia Maps.": "Stadia Maps 的 API 密钥",
"Style Renderer": "样式渲染器",
"Choose the default Maputnik renderer for this style.": "为这种样式选择默认的Maputnik渲染器。",
"<0>Open in OSM</0> — Opens the current view on openstreetmap.org": "在 openstreetmap.org 打开当前视图",
"Layer options": "图层选项",
"Paint properties": "绘制属性",
"Layout properties": "布局属性",