mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-04 20:03:45 +00:00
Compare commits
107 Commits
test/2025.
...
jb_err_msg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f617e4af9 | ||
|
|
07e42c0626 | ||
|
|
14e45aa6db | ||
|
|
8bd7f9d59a | ||
|
|
ead092af79 | ||
|
|
c3f5986f12 | ||
|
|
143e0562e6 | ||
|
|
89cfc6f8e6 | ||
|
|
4788956720 | ||
|
|
f6ff08619e | ||
|
|
a4df3eaad5 | ||
|
|
55f55bbde1 | ||
|
|
c6abf26628 | ||
|
|
5b9b9929b8 | ||
|
|
d1aa8f5905 | ||
|
|
50130f9880 | ||
|
|
9923a28951 | ||
|
|
ff51988ddf | ||
|
|
7f693b9dfd | ||
|
|
42f0855ec8 | ||
|
|
008a785564 | ||
|
|
a62f9470ec | ||
|
|
bfe65e0de0 | ||
|
|
eee0401a66 | ||
|
|
4226e2f999 | ||
|
|
94bcd5f366 | ||
|
|
1b64151aee | ||
|
|
899df496ba | ||
|
|
47f959ec07 | ||
|
|
6e8a0f22e6 | ||
|
|
2a2007a473 | ||
|
|
db91e3ea92 | ||
|
|
3705abbbd6 | ||
|
|
f33bfffbe6 | ||
|
|
72eeceb021 | ||
|
|
372a7f47d3 | ||
|
|
49f4971015 | ||
|
|
45224d1bd0 | ||
|
|
26ec203e41 | ||
|
|
ee1081bc7d | ||
|
|
5050dea70f | ||
|
|
9bb29578d0 | ||
|
|
33e4894a56 | ||
|
|
aa34159ce8 | ||
|
|
1ccea5928f | ||
|
|
ec59698f4a | ||
|
|
0c2763f3ce | ||
|
|
c9a4483f50 | ||
|
|
0eafe3482e | ||
|
|
e4275cdd3c | ||
|
|
4ef9395442 | ||
|
|
30cf2b5770 | ||
|
|
6aed26c48e | ||
|
|
dad91b82a6 | ||
|
|
7024aace6f | ||
|
|
6291133a69 | ||
|
|
1c5121d447 | ||
|
|
4398e492b8 | ||
|
|
1907e039e3 | ||
|
|
26bad5dffb | ||
|
|
4f2b479b2c | ||
|
|
a972552155 | ||
|
|
dc54c45482 | ||
|
|
1975b6a0f0 | ||
|
|
8683853f46 | ||
|
|
d7e34c2685 | ||
|
|
0028306b26 | ||
|
|
b5354fd1e3 | ||
|
|
964f82510a | ||
|
|
faf49fc574 | ||
|
|
60b1ad232a | ||
|
|
1bac0fd4fc | ||
|
|
ed6dcc5cb2 | ||
|
|
33b440dd71 | ||
|
|
6a20269819 | ||
|
|
8cd1b41cd2 | ||
|
|
2b630964d0 | ||
|
|
76ecd8209e | ||
|
|
82d2932ba0 | ||
|
|
85540133b3 | ||
|
|
6ded75de9c | ||
|
|
08e8ebd434 | ||
|
|
6c92264fb0 | ||
|
|
4ba0fc51a5 | ||
|
|
29c363a581 | ||
|
|
4973f4fed2 | ||
|
|
8cffa508f3 | ||
|
|
3511dbb692 | ||
|
|
e238a317f1 | ||
|
|
2e85899fcb | ||
|
|
ce978d8ede | ||
|
|
d56f9700f5 | ||
|
|
cc042c3d1c | ||
|
|
4f739d98b0 | ||
|
|
4691de7a66 | ||
|
|
3c082b0629 | ||
|
|
a468bd3fab | ||
|
|
fc87316184 | ||
|
|
298518ae72 | ||
|
|
3bad6d25f0 | ||
|
|
d36361d669 | ||
|
|
688e20b1a6 | ||
|
|
85462161b2 | ||
|
|
b929823f6b | ||
|
|
22dd799585 | ||
|
|
6864d101e2 | ||
|
|
4bfb62b373 |
@@ -1,69 +1,55 @@
|
|||||||
# All non-assigned.
|
|
||||||
* @organicmaps/mergers
|
|
||||||
# Visual design.
|
# Visual design.
|
||||||
/android/app/src/main/res/drawable*/ @organicmaps/design
|
/android/app/src/main/res/drawable*/ @comaps/design
|
||||||
/android/app/src/main/res/font/ @organicmaps/design
|
/android/app/src/main/res/font/ @comaps/design
|
||||||
/android/app/src/main/res/mipmap*/ @organicmaps/design
|
/android/app/src/main/res/mipmap*/ @comaps/design
|
||||||
/data/*.ttf @organicmaps/design
|
/data/*.ttf @comaps/design
|
||||||
/data/resources-svg/ @organicmaps/design
|
/data/resources-svg/ @comaps/design
|
||||||
/data/search-icons/ @organicmaps/design
|
/data/search-icons/ @comaps/design
|
||||||
/iphone/Maps/Images.xcassets/ @organicmaps/design
|
/iphone/Maps/Images.xcassets/ @comaps/design
|
||||||
# Android.
|
# Android.
|
||||||
/android/ @organicmaps/android
|
/android/ @comaps/android
|
||||||
/android/app/src/main/java/app/organicmaps/car/ @organicmaps/android-auto
|
/android/app/src/main/java/app/comaps/car/ @comaps/android-auto
|
||||||
/docs/ANDROID_LOCATION_TEST.md @organicmaps/android
|
/docs/ANDROID_LOCATION_TEST.md @comaps/android
|
||||||
/docs/JAVA_STYLE.md @organicmaps/android
|
/docs/JAVA_STYLE.md @comaps/android
|
||||||
# no owner for translation changes
|
# no owner for translation changes
|
||||||
/android/app/src/main/res/values*/strings.xml
|
/android/app/src/main/res/values*/strings.xml
|
||||||
# iOS.
|
# iOS.
|
||||||
/iphone/ @organicmaps/ios
|
/iphone/ @comaps/ios
|
||||||
/xcode/ @organicmaps/ios
|
/xcode/ @comaps/ios
|
||||||
/docs/OBJC_STYLE.md @organicmaps/ios
|
/docs/OBJC_STYLE.md @comaps/ios
|
||||||
# no owner for translation changes
|
# no owner for translation changes
|
||||||
/iphone/plist.txt
|
/iphone/plist.txt
|
||||||
/iphone/Maps/LocalizedStrings/
|
/iphone/Maps/LocalizedStrings/
|
||||||
# Qt
|
|
||||||
/qt/ @organicmaps/qt
|
|
||||||
# Rendering
|
|
||||||
/drape/ @organicmaps/rendering
|
|
||||||
/drape_frontend/ @organicmaps/rendering
|
|
||||||
# Map Data.
|
|
||||||
/tools/python/maps_generator/ @organicmaps/data
|
|
||||||
/generator/ @organicmaps/data
|
|
||||||
/topography_generator/ @organicmaps/data
|
|
||||||
/data/borders/ @organicmaps/data
|
|
||||||
/data/conf/isolines/ @organicmaps/data
|
|
||||||
/docs/SUBWAY_GENERATION.md @organicmaps/data
|
|
||||||
/docs/MAPS.md @organicmaps/data
|
|
||||||
/docs/EXPERIMENTAL_PUBLIC_TRANSPORT_SUPPORT.md @organicmaps/data
|
|
||||||
# no owner (changed often to add a new POI)
|
# no owner (changed often to add a new POI)
|
||||||
/generator/generator_tests/osm_type_test.cpp
|
/generator/generator_tests/osm_type_test.cpp
|
||||||
# Map Styles.
|
# Map Styles.
|
||||||
/data/styles/ @organicmaps/styles
|
/data/styles/ @comaps/styles
|
||||||
/data/types.txt @organicmaps/styles
|
/data/types.txt @comaps/styles
|
||||||
/data/visibility.txt @organicmaps/styles
|
/data/visibility.txt @comaps/styles
|
||||||
/data/mapcss-mapping.csv @organicmaps/styles
|
/data/mapcss-mapping.csv @comaps/styles
|
||||||
/data/replaced_tags.txt @organicmaps/styles
|
/data/replaced_tags.txt @comaps/styles
|
||||||
/data/classificator.txt @organicmaps/styles
|
/data/classificator.txt @comaps/styles
|
||||||
/data/drules_* @organicmaps/styles
|
/data/drules_* @comaps/styles
|
||||||
/docs/STYLES.md
|
/docs/STYLES.md
|
||||||
/tools/kothic/ @organicmaps/styles
|
/tools/kothic/ @comaps/styles
|
||||||
# DevOps.
|
# DevOps.
|
||||||
/.forgejo/workflows @organicmaps/devops
|
/.forgejo/workflows @comaps/devops
|
||||||
/android/*gradle* @organicmaps/devops
|
/android/*gradle* @comaps/devops
|
||||||
/docs/RELEASE_MANAGEMENT.md @organicmaps/devops
|
/docs/RELEASE_MANAGEMENT.md @comaps/devops
|
||||||
/xcode/fastlane/ @organicmaps/devops
|
/xcode/fastlane/ @comaps/devops
|
||||||
# Growth.
|
/tools/python/maps_generator/ @comaps/devops
|
||||||
README.md @organicmaps/growth
|
/generator/ @comaps/devops
|
||||||
/.forgejo/FUNDING.yml @organicmaps/growth
|
/topography_generator/ @comaps/devops
|
||||||
/android/app/src/fdroid/play/ @organicmaps/growth
|
/data/borders/ @comaps/devops
|
||||||
/android/app/src/google/play/ @organicmaps/growth
|
/data/conf/isolines/ @comaps/devops
|
||||||
/iphone/metadata/ @organicmaps/growth
|
/docs/SUBWAY_GENERATION.md @comaps/devops
|
||||||
|
/docs/MAPS.md @comaps/devops
|
||||||
|
/docs/EXPERIMENTAL_PUBLIC_TRANSPORT_SUPPORT.md @comaps/devops
|
||||||
# Legal.
|
# Legal.
|
||||||
LEGAL @organicmaps/legal
|
LEGAL @comaps/admins
|
||||||
LICENSE @organicmaps/legal
|
LICENSE @comaps/admins
|
||||||
NOTICE @organicmaps/legal
|
NOTICE @comaps/admins
|
||||||
CONTRIBUTORS @organicmaps/legal
|
CONTRIBUTORS @comaps/admins
|
||||||
/docs/CODE_OF_CONDUCT.md @organicmaps/legal
|
/docs/CODE_OF_CONDUCT.md @comaps/admins
|
||||||
/docs/DCO.md @organicmaps/legal
|
/docs/DCO.md @comaps/admins
|
||||||
/docs/GOVERNANCE.md @organicmaps/legal
|
/docs/GOVERNANCE.md @comaps/admins
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
open_collective: comaps
|
open_collective: comaps
|
||||||
|
liberapay: comaps
|
||||||
|
custom: ["https://comaps.app/donate/"]
|
||||||
|
|||||||
129
.forgejo/workflows/process_subways.yml
Normal file
129
.forgejo/workflows/process_subways.yml
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
name: process_subways
|
||||||
|
on:
|
||||||
|
workflow_dispatch: # Manual trigger
|
||||||
|
|
||||||
|
env:
|
||||||
|
PLANET: /home/planet/planet/planet.o5m
|
||||||
|
TMPDIR: /tmp
|
||||||
|
HTML_DIR: "/mnt/4tbexternal/osm-planet/subway/validator"
|
||||||
|
DUMP: "$HTML_DIR"
|
||||||
|
SKIP_PLANET_UPDATE: "1"
|
||||||
|
DEBIAN_FRONTEND: nonnteractive
|
||||||
|
TZ: Etc/UTC
|
||||||
|
|
||||||
|
# /var/www/html/subways is mapped as a volume on cdn-fi-1
|
||||||
|
# as is /tmp/planet
|
||||||
|
jobs:
|
||||||
|
clone-repos:
|
||||||
|
name: Clone Git Repos
|
||||||
|
runs-on: mapfilemaker
|
||||||
|
container:
|
||||||
|
image: codeberg.org/comaps/maps_generator:f6d53d54f794
|
||||||
|
volumes:
|
||||||
|
- /mnt/4tbexternal:/mnt/4tbexternal
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-process-subways-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
steps:
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: "~"
|
||||||
|
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||||
|
- name: Checkout subways repo
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd ~
|
||||||
|
git clone --depth 1 --single-branch https://codeberg.org/comaps/subways.git
|
||||||
|
|
||||||
|
update-planet-o5m:
|
||||||
|
name: Update O5M Planet
|
||||||
|
runs-on: mapfilemaker
|
||||||
|
container:
|
||||||
|
image: codeberg.org/comaps/maps_generator:f6d53d54f794
|
||||||
|
volumes:
|
||||||
|
- /mnt/4tbexternal/:/mnt/4tbexternal/
|
||||||
|
- /mnt/4tbexternal/osm-planet:/home/planet
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-process-subways-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
steps:
|
||||||
|
- name: Check for O5M Planet File
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [ ! -f /home/planet/planet/planet.o5m ]; then
|
||||||
|
echo "WARN: No file at /home/planet/planet/planet.o5m"
|
||||||
|
|
||||||
|
if [ ! -f /home/planet/planet/planet-latest.osm.pbf ]; then
|
||||||
|
echo "ERROR: No file at /home/planet/planet/planet-latest.osm.pbf"
|
||||||
|
ls -al /home/planet/
|
||||||
|
ls -al /home/planet/planet/
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Converting planet-latest.osm.pbf to planet.o5m"
|
||||||
|
cd /home/planet/planet/
|
||||||
|
osmconvert -v --drop-author --drop-version --hash-memory=4000 planet-latest.osm.pbf -o=planet.o5m
|
||||||
|
echo "Conversion is done."
|
||||||
|
fi
|
||||||
|
- name: Update O5M planet
|
||||||
|
run: |
|
||||||
|
echo "Starting..."
|
||||||
|
cd /home/planet/planet/
|
||||||
|
rm -f planet-new.o5m
|
||||||
|
osmupdate -v --drop-author --drop-version --hash-memory=4000 --max-merge=32 --out-o5m planet.o5m planet-new.o5m
|
||||||
|
mv planet-new.o5m planet.o5m
|
||||||
|
echo "Done."
|
||||||
|
- name: Notify Zulip
|
||||||
|
run: |
|
||||||
|
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
|
||||||
|
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
|
||||||
|
--data-urlencode type=stream \
|
||||||
|
--data-urlencode 'to="DevOps"' \
|
||||||
|
--data-urlencode topic=codeberg-bot \
|
||||||
|
--data-urlencode 'content=O5M planet update is done!'
|
||||||
|
|
||||||
|
update-subways:
|
||||||
|
if: inputs.run-subways
|
||||||
|
name: Update Subways
|
||||||
|
runs-on: mapfilemaker
|
||||||
|
needs:
|
||||||
|
- clone-repos
|
||||||
|
container:
|
||||||
|
image: codeberg.org/comaps/maps_generator:f6d53d54f794
|
||||||
|
volumes:
|
||||||
|
- /mnt/4tbexternal/:/mnt/4tbexternal/
|
||||||
|
- /mnt/4tbexternal/osm-planet:/home/planet
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
steps:
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: "~"
|
||||||
|
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||||
|
- name: Update Subways
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd ~/comaps/
|
||||||
|
cp tools/unix/maps/settings.sh.prod tools/unix/maps/settings.sh
|
||||||
|
./tools/unix/maps/generate_subways.sh
|
||||||
|
- name: Compare with VK validation
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd ~/subways
|
||||||
|
if [ -f "$HTML_DIR/index.html" ]; then
|
||||||
|
echo "Comparing local validation with VK's validation..."
|
||||||
|
python3 ./scripts/compare_html_validation.py "$HTML_DIR/index.html" \
|
||||||
|
--vk-url "https://maps.vk.com/osm/tools/subways/latest/index.html"
|
||||||
|
else
|
||||||
|
echo "Local index.html not found at $HTML_DIR/index.html"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- name: Notify Zulip
|
||||||
|
run: |
|
||||||
|
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
|
||||||
|
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
|
||||||
|
--data-urlencode type=stream \
|
||||||
|
--data-urlencode 'to="DevOps"' \
|
||||||
|
--data-urlencode topic=codeberg-bot \
|
||||||
|
--data-urlencode 'content=Subways are done!'
|
||||||
@@ -2,5 +2,3 @@
|
|||||||
480fa6c2fcf53be296504ac6ba8e6b3d70f92b42
|
480fa6c2fcf53be296504ac6ba8e6b3d70f92b42
|
||||||
a6ede2b1466f0c9d8a443600ef337ba6b5832e58
|
a6ede2b1466f0c9d8a443600ef337ba6b5832e58
|
||||||
1377b81bf1cac72bb6da192da7fed6696d5d5281
|
1377b81bf1cac72bb6da192da7fed6696d5d5281
|
||||||
99900fad21bab3f97065d11562346c5525a31f57
|
|
||||||
a53828154fc7aa363dfe8926affaea56237832e5
|
|
||||||
|
|||||||
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
open_collective: comaps
|
||||||
|
liberapay: comaps
|
||||||
|
custom: ["https://comaps.app/donate/"]
|
||||||
6
.github/workflows/android-check.yaml
vendored
6
.github/workflows/android-check.yaml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ jobs:
|
|||||||
pip install "protobuf<3.21" --break-system-packages
|
pip install "protobuf<3.21" --break-system-packages
|
||||||
|
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 200 # enough to get all commits for the current day
|
fetch-depth: 200 # enough to get all commits for the current day
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ jobs:
|
|||||||
./gradlew -P${{ matrix.arch }} assemble${{ matrix.flavor }}
|
./gradlew -P${{ matrix.arch }} assemble${{ matrix.flavor }}
|
||||||
|
|
||||||
- name: Upload ${{ matrix.flavor }} apk
|
- name: Upload ${{ matrix.flavor }} apk
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: android-${{ matrix.flavor }}
|
name: android-${{ matrix.flavor }}
|
||||||
path: android/app/build/outputs/apk/**/CoMaps-*.apk
|
path: android/app/build/outputs/apk/**/CoMaps-*.apk
|
||||||
|
|||||||
2
.github/workflows/ios-check.yaml
vendored
2
.github/workflows/ios-check.yaml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
xcodebuild -downloadPlatform iOS
|
xcodebuild -downloadPlatform iOS
|
||||||
|
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Parallel submodules checkout
|
- name: Parallel submodules checkout
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -155,6 +155,8 @@ android/huawei-appgallery.json
|
|||||||
android/res/xml/network_security_config.xml
|
android/res/xml/network_security_config.xml
|
||||||
./server/
|
./server/
|
||||||
iphone/Maps/app.omaps/
|
iphone/Maps/app.omaps/
|
||||||
|
# Generated file
|
||||||
|
libs/indexer/localized_types_map.cpp
|
||||||
|
|
||||||
*.li
|
*.li
|
||||||
|
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
///////////////////////// ankerl::unordered_dense::{map, set} /////////////////////////
|
|
||||||
|
|
||||||
// A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion.
|
|
||||||
// Version 4.8.1
|
|
||||||
// https://github.com/martinus/unordered_dense
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// Copyright (c) 2022 Martin Leitner-Ankerl <martin.ankerl@gmail.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
#ifndef ANKERL_STL_H
|
|
||||||
#define ANKERL_STL_H
|
|
||||||
|
|
||||||
#include <array> // for array
|
|
||||||
#include <cstdint> // for uint64_t, uint32_t, std::uint8_t, UINT64_C
|
|
||||||
#include <cstring> // for size_t, memcpy, memset
|
|
||||||
#include <functional> // for equal_to, hash
|
|
||||||
#include <initializer_list> // for initializer_list
|
|
||||||
#include <iterator> // for pair, distance
|
|
||||||
#include <limits> // for numeric_limits
|
|
||||||
#include <memory> // for allocator, allocator_traits, shared_ptr
|
|
||||||
#include <optional> // for optional
|
|
||||||
#include <stdexcept> // for out_of_range
|
|
||||||
#include <string> // for basic_string
|
|
||||||
#include <string_view> // for basic_string_view, hash
|
|
||||||
#include <tuple> // for forward_as_tuple
|
|
||||||
#include <type_traits> // for enable_if_t, declval, conditional_t, ena...
|
|
||||||
#include <utility> // for forward, exchange, pair, as_const, piece...
|
|
||||||
#include <vector> // for vector
|
|
||||||
|
|
||||||
// <memory_resource> includes <mutex>, which fails to compile if
|
|
||||||
// targeting GCC >= 13 with the (rewritten) win32 thread model, and
|
|
||||||
// targeting Windows earlier than Vista (0x600). GCC predefines
|
|
||||||
// _REENTRANT when using the 'posix' model, and doesn't when using the
|
|
||||||
// 'win32' model.
|
|
||||||
#if defined __MINGW64__ && defined __GNUC__ && __GNUC__ >= 13 && !defined _REENTRANT
|
|
||||||
// _WIN32_WINNT is guaranteed to be defined here because of the
|
|
||||||
// <cstdint> inclusion above.
|
|
||||||
# ifndef _WIN32_WINNT
|
|
||||||
# error "_WIN32_WINNT not defined"
|
|
||||||
# endif
|
|
||||||
# if _WIN32_WINNT < 0x600
|
|
||||||
# define ANKERL_MEMORY_RESOURCE_IS_BAD() 1 // NOLINT(cppcoreguidelines-macro-usage)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifndef ANKERL_MEMORY_RESOURCE_IS_BAD
|
|
||||||
# define ANKERL_MEMORY_RESOURCE_IS_BAD() 0 // NOLINT(cppcoreguidelines-macro-usage)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__has_include) && !defined(ANKERL_UNORDERED_DENSE_DISABLE_PMR)
|
|
||||||
# if __has_include(<memory_resource>) && !ANKERL_MEMORY_RESOURCE_IS_BAD()
|
|
||||||
# define ANKERL_UNORDERED_DENSE_PMR std::pmr // NOLINT(cppcoreguidelines-macro-usage)
|
|
||||||
# include <memory_resource> // for polymorphic_allocator
|
|
||||||
# elif __has_include(<experimental/memory_resource>)
|
|
||||||
# define ANKERL_UNORDERED_DENSE_PMR std::experimental::pmr // NOLINT(cppcoreguidelines-macro-usage)
|
|
||||||
# include <experimental/memory_resource> // for polymorphic_allocator
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_M_X64)
|
|
||||||
# include <intrin.h>
|
|
||||||
# pragma intrinsic(_umul128)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -116,20 +116,6 @@ endif()
|
|||||||
|
|
||||||
message(STATUS "Build type: " ${CMAKE_BUILD_TYPE})
|
message(STATUS "Build type: " ${CMAKE_BUILD_TYPE})
|
||||||
|
|
||||||
if (PLATFORM_LINUX OR PLATFORM_ANDROID)
|
|
||||||
find_program(LLD_FOUND ld.lld)
|
|
||||||
if (LLD_FOUND)
|
|
||||||
message(STATUS "Using ld.lld linker")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld")
|
|
||||||
else()
|
|
||||||
find_program(GOLD_FOUND ld.gold)
|
|
||||||
if (GOLD_FOUND)
|
|
||||||
message(STATUS "Using ld.gold")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=gold")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT SKIP_TESTS)
|
if (NOT SKIP_TESTS)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
# Enables ctest -T memcheck with valgrind
|
# Enables ctest -T memcheck with valgrind
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ CoMaps contributors:
|
|||||||
Bastian Greshake Tzovaras
|
Bastian Greshake Tzovaras
|
||||||
clover sage
|
clover sage
|
||||||
Harry Bond <me@hbond.xyz>
|
Harry Bond <me@hbond.xyz>
|
||||||
|
NoelClick
|
||||||
thesupertechie
|
thesupertechie
|
||||||
vikiawv
|
vikiawv
|
||||||
Yannik Bloscheck
|
Yannik Bloscheck
|
||||||
|
|||||||
2
NOTICE
2
NOTICE
@@ -1,6 +1,6 @@
|
|||||||
Copyright 2020 My.com B.V. (Mail.Ru Group)
|
Copyright 2020 My.com B.V. (Mail.Ru Group)
|
||||||
Copyright 2025 Organic Maps Contributors
|
Copyright 2025 Organic Maps Contributors
|
||||||
Copyright 2025 CoMaps Contributors
|
Copyright 2026 CoMaps Contributors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
17
SECURITY.md
Normal file
17
SECURITY.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
## Reporting Vulnerabilities
|
||||||
|
You can report a security vulnerability by creating an issue or send mail to security@comaps.app
|
||||||
|
|
||||||
|
## Verifying Fingerprints
|
||||||
|
|
||||||
|
To [verify](https://developer.android.com/studio/command-line/apksigner#usage-verify) the APK, use the following signing certificate fingerprints:
|
||||||
|
```
|
||||||
|
SHA-256: 4894e8e6963627ef660031d8593fe77297f835acb4e23810003e926135023b4c
|
||||||
|
SHA-1: 8b7b5739f917e9f7c681671ced0c9c8562123ade
|
||||||
|
MD5: 9cce0ffea281dc2f0e0a154d6d2e281e
|
||||||
|
```
|
||||||
|
|
||||||
|
To verify CoMaps via [AppVerifier](https://github.com/soupslurpr/AppVerifier), use the following signing certificate fingerprint:
|
||||||
|
```
|
||||||
|
app.comaps
|
||||||
|
48:94:E8:E6:96:36:27:EF:66:00:31:D8:59:3F:E7:72:97:F8:35:AC:B4:E2:38:10:00:3E:92:61:35:02:3B:4C
|
||||||
|
```
|
||||||
@@ -351,6 +351,8 @@ dependencies {
|
|||||||
implementation libs.androidx.recyclerview
|
implementation libs.androidx.recyclerview
|
||||||
implementation libs.androidx.work.runtime
|
implementation libs.androidx.work.runtime
|
||||||
implementation libs.androidx.lifecycle.process
|
implementation libs.androidx.lifecycle.process
|
||||||
|
implementation libs.androidx.documentfile
|
||||||
|
// 1.13 Material library version doesn't render properly alpha properties on map buttons
|
||||||
implementation libs.android.material
|
implementation libs.android.material
|
||||||
// Fix for app/organicmaps/util/FileUploadWorker.java:14: error: cannot access ListenableFuture
|
// Fix for app/organicmaps/util/FileUploadWorker.java:14: error: cannot access ListenableFuture
|
||||||
// https://github.com/organicmaps/organicmaps/issues/6106
|
// https://github.com/organicmaps/organicmaps/issues/6106
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Eine von der Community betriebene, kostenlose Open-Source Karten-App, die auf OpenStreetMap Daten basiert. Transparent und nicht gewinnorientiert. CoMaps ist ein Fork/Abspaltung von Organic Maps, die wiederum ein Fork/Abspaltung von Maps.Me ist.
|
Eine von der Community betriebene, kostenlose Open-Source Karten-App, die auf OpenStreetMap Daten basiert. Transparent und nicht gewinnorientiert. CoMaps ist ein Fork/Abspaltung von Organic Maps, die wiederum ein Fork/Abspaltung von Maps.Me ist.
|
||||||
|
|
||||||
Lese mehr über die Gründe und Ziele des Projektes unter <b><i>codeberg.org/comaps</i></b>.
|
Lese mehr über die Gründe und Ziele des Projektes unter <b><i>codeberg.org/comaps</i></b> (auf Englisch).
|
||||||
Werde Teil der Community und hilf mit, die beste Karten-App zu entwickeln
|
Werde Teil der Community und hilf mit, die beste Karten-App zu entwickeln
|
||||||
• Nutze die App und erzähle anderen davon
|
• Nutze die App und erzähle anderen davon
|
||||||
• Gib Feedback und melde Probleme
|
• Gib Feedback und melde Probleme
|
||||||
@@ -9,9 +9,9 @@ Werde Teil der Community und hilf mit, die beste Karten-App zu entwickeln
|
|||||||
‣ <b>Einfach und ausgereift</b>: Essenzielle, leicht zu bedienende Funktionen, die einfach funktionieren.
|
‣ <b>Einfach und ausgereift</b>: Essenzielle, leicht zu bedienende Funktionen, die einfach funktionieren.
|
||||||
‣ <b>Offline-orientiert</b>: Plane und navigiere im Ausland ohne Mobilfunkverbindung, finde Wegpunkte auf abgelegenen Wanderungen usw. Alle Funktionen sind für den Offline-Einsatz konzipiert.
|
‣ <b>Offline-orientiert</b>: Plane und navigiere im Ausland ohne Mobilfunkverbindung, finde Wegpunkte auf abgelegenen Wanderungen usw. Alle Funktionen sind für den Offline-Einsatz konzipiert.
|
||||||
‣ <b>Datenschutzfreundlich</b>: Die App wurde mit Fokus auf Privatsphäre entwickelt – keine Personenidentifikation, kein Tracking, keine Erfassung persönlicher Daten, keine Werbung.
|
‣ <b>Datenschutzfreundlich</b>: Die App wurde mit Fokus auf Privatsphäre entwickelt – keine Personenidentifikation, kein Tracking, keine Erfassung persönlicher Daten, keine Werbung.
|
||||||
‣ <b>Spart Akku und Speicherplatz</b>: Verbraucht nicht unnötig Akku wie andere Navi-Apps. Kompakte Karten sparen Speicherplatz auf deinem Gerät.
|
‣ <b>Spart Akku und Speicherplatz</b>: Verbraucht nicht unnötig viel Akku wie andere Navi-Apps. Kompakte Karten sparen Speicherplatz auf deinem Gerät.
|
||||||
‣ <b>Kostenlos und von der Community entwickelt</b>: Menschen wie du haben geholfen, diese App zu entwickeln – durch das Hinzufügen von Orten zu OpenStreetMap, Testen von neuen Funktionen, Softwareentwicklung oder Spenden.
|
‣ <b>Kostenlos und von der Community entwickelt</b>: Menschen wie du haben geholfen, diese App zu entwickeln – durch das Hinzufügen von Orten zu OpenStreetMap, Testen von neuen Funktionen, Softwareentwicklung oder Spenden.
|
||||||
‣ <b>Offen und transparent bei Entscheidungen und Finanzen, gemeinnützig und vollständig Open-Source</b>
|
‣ <b>Offen und transparent bei Entscheidungen und Finanzen, gemeinnützig und vollständig Open-Source.</b>
|
||||||
|
|
||||||
<b>Hauptfunktionen</b>:
|
<b>Hauptfunktionen</b>:
|
||||||
• Detaillierte, herunterladbare Karten mit Orten, die bei Google Maps oft fehlen
|
• Detaillierte, herunterladbare Karten mit Orten, die bei Google Maps oft fehlen
|
||||||
@@ -28,5 +28,5 @@ Werde Teil der Community und hilf mit, die beste Karten-App zu entwickeln
|
|||||||
• Dunkler Modus für die Nutzung bei Nacht
|
• Dunkler Modus für die Nutzung bei Nacht
|
||||||
• Kartenbearbeitung direkt in der App mit einem einfachen Editor
|
• Kartenbearbeitung direkt in der App mit einem einfachen Editor
|
||||||
|
|
||||||
<b>Entdecke die Unabhängigkeit</b>
|
<b>Freiheit beginnt hier</b>
|
||||||
Entdecke deine Reise – navigiere in der Welt mit Datenschutz!
|
Entdecke deine Reise, wobei Datenschutz und Gemeinschaft im Vordergrund stehen!
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
• OpenStreetMap-Daten vom 9. Dezember
|
• OpenStreetMap Daten vom 17. Dezember
|
||||||
• Material 3 Design
|
• Map download server nun wählbar
|
||||||
• Im OSM-Editor können nun Ladestationen hinzugefügt werden
|
• Warnung über veraltete Karten hinzugefügt + Knopf zum updaten
|
||||||
• Schuko und Typ E Ladestationen hinzugefügt
|
• Vermeidung von Parkplatzwegen im Routing
|
||||||
• Verbesserte Suchvorschläge
|
• Neuer Zoombutton
|
||||||
• Litauische und lettische Sprachankündigungen
|
• Verbesserte Französchische Suchsynonme
|
||||||
• Die Fahranweisungen wurden vergrößert
|
• OSM editor: Maximale Länge für OSM-Tags werden nun geprüft
|
||||||
• Der Zoomlevel passt sich an die Distanz zur nächsten Abbiegung an
|
Mehr auf codeberg.org/comaps/comaps/releases
|
||||||
• Neue Anordnung der Einstellungen
|
|
||||||
Weitere Einzelheiten auf codeberg.org/comaps/comaps/releases
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Einfache Navigation - Entdecken Sie mehr von Ihrer Reise - Community-Entwickelt
|
Leichte Navigation – Erlebe mehr von deiner Reise – Community-unterstützt
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
• OpenStreetMap data as of December 9
|
• OpenStreetMap data as of December 17
|
||||||
• Use Material 3 themes
|
• Make map download server configurable
|
||||||
• Support charging sockets in OSM Editor
|
• Added info about outdated maps and an update button to the selected place info card
|
||||||
• Added schuko/type-E charge sockets
|
• Avoid using parking aisles for routing
|
||||||
• Improved search results ranking
|
• Changed shape of zoom buttons
|
||||||
• Enabled Lithuanian and Latvian in voice announcements
|
• Improved French search synonyms
|
||||||
• Improved size of driving indications
|
• OSM editor: check length limit for OSM tags in value validation
|
||||||
• Base zoom level on distance to next turn
|
|
||||||
• Reordered settings
|
|
||||||
More details on codeberg.org/comaps/comaps/releases
|
More details on codeberg.org/comaps/comaps/releases
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
• Datos de OpenStreetMap a fecha 9/12.
|
|
||||||
• Uso de temas Material 3.
|
|
||||||
• Compatibilidad con enchufes de recarga en Editor.
|
|
||||||
• Se añaden enchufes de recarga schuko/tipo E.
|
|
||||||
• Se mejora la búsqueda.
|
|
||||||
• Se habilitan el lituano y el letón en las indicaciones de voz.
|
|
||||||
• Se aumenta el tamaño de las indicaciones de conducción.
|
|
||||||
• Nivel de zoom base según la distancia al siguiente giro.
|
|
||||||
• Se han reordenado los ajustes.
|
|
||||||
|
|
||||||
Más detalles en codeberg.org/comaps/comaps/releases
|
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
• Données OpenStreetMap du 9 Décembre
|
• Données OpenStreetMap du 17 décembre
|
||||||
• Utilisation de Material 3
|
• Serveur de téléchargement de cartes configurable
|
||||||
• Support de l'édition des bornes de recharge dans l'éditeur OSM
|
• Ajout d'un message d'avertissement pour les cartes trop anciennes
|
||||||
• Ajout du type de prise schuko/type-E
|
• Évitement des allées de parking dans les itinéraires
|
||||||
• Amélioration de l'ordre des résultats de recherche
|
• Mise à jour de l'apparence des boutons de zooms
|
||||||
• Ajout du lituanien et du letton dans le guidage vocal
|
• Amélioration des synonymes de recherche en français
|
||||||
• Amélioration de la taille des instructions dans la navigation
|
• Editeur OSM: vérification de la taille limite des tags OSM
|
||||||
• Niveau de zoom basé sur la distance jusqu’au prochain virage
|
Plus d'informations sur codeberg.org/comaps/comaps/releases
|
||||||
• Réorganisation des paramètres
|
|
||||||
Plus de détails sur codeberg.org/comaps/comaps/releases
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
• Podaci OpenStreetMap karte od 9. prosinca
|
|
||||||
• Korištenje Material 3 tema
|
|
||||||
• Podrška za utičnice za punjenje u OSM Editoru
|
|
||||||
• Dodane šuko/tip-E utičnice
|
|
||||||
• Poboljšano rangiranje rezultata pretraživanja
|
|
||||||
• Omogućeni litvanski i latvijski jezici u glasovnim najavama
|
|
||||||
• Povećana veličina indikatora vožnje
|
|
||||||
• Razina zumiranja se mijenja ovisno o udaljenosti do sljedećeg skretanja
|
|
||||||
• Promijenjen redoslijed postavki
|
|
||||||
Više detalja na codeberg.org/comaps/comaps/releases
|
|
||||||
32
android/app/src/fdroid/play/listings/lt/full-description.txt
Normal file
32
android/app/src/fdroid/play/listings/lt/full-description.txt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
Bendruomenės vystoma nemokama atvirojo kodo žemėlapių programa, pagrįsta „OpenStreetMap“ duomenimis ir sustiprinta įsipareigojimu užtikrinti skaidrumą, privatumą ir pelno nesiekimą. „CoMaps“ programa yra kilusi iš „Organic Maps“, o pastaroji – iš programos „Maps.ME“.
|
||||||
|
|
||||||
|
Apie šio projekto kilmę, jos priežastis ir palaikomą kryptį galite paskaityti adresu <b><i>codeberg.org/comaps</i></b>.
|
||||||
|
Prisijunkite prie bendruomenės ir padėkite sukurti geriausią žemėlapių programą
|
||||||
|
• Naudokitės programa ir paskleiskite žinią apie ją
|
||||||
|
• Teikite atsiliepimus ir praneškite apie problemas
|
||||||
|
• Atnaujinkite žemėlapių duomenis programoje arba „OpenStreetMap“ svetainėje
|
||||||
|
|
||||||
|
‣ <b>Skirta naudoti neprisijungus prie interneto</b>: planuokite maršrutus ir keliaukite užsienyje be mobiliojo ryšio, ieškokite kelionės taškų tolimuose žygiuose ir pan. Visos programos funkcijos yra pritaikytos veikti be interneto ryšio.
|
||||||
|
‣ <b>Gerbia privatumą</b>: programėlė sukurta, teikiant prioritetą privatumui: neidentifikuoja žmonių, neseka ir nerenka asmeninės informacijos. Be reklamų.
|
||||||
|
‣ <b>Paprasta ir išbaigta</b>: esminės, lengvai naudojamos funkcijos, kurios tiesiog veikia.
|
||||||
|
‣ <b>Taupo bateriją ir vietą</b>: neišsekina baterijos kaip kitos navigacijos programos. Kompaktiški žemėlapiai tausoja vietą jūsų telefone.
|
||||||
|
‣ <b>Nemokama ir kuriama bendruomenės</b>: paprasti žmonės – kaip jūs – padėjo sukurti šią programą, pildydami „OpenStreetMap“ žemėlapį, išbandydami ir pateikdami atsiliepimus apie funkcijas bei prisidėdami savo programavimo įgūdžiais ir pinigais.
|
||||||
|
‣ <b>Atviras ir skaidrus sprendimų priėmimas ir finansai, ne pelno siekianti ir visiškai atviro kodo programa.</b>
|
||||||
|
|
||||||
|
<b>Pagrindinės funkcijos</b>:
|
||||||
|
• Atsisiunčiami išsamūs žemėlapiai su vietomis, kurių nėra „Google Maps“;
|
||||||
|
• Žygių pėsčiomis veiksena su pažymėtais pėsčiųjų takais, stovyklavietėmis, vandens šaltiniais, kalnų viršūnėmis, reljefo linijomis ir kt.;
|
||||||
|
• Pėsčiųjų ir dviračių takai;
|
||||||
|
• Potencialūs kelionės taškai, kaip antai restoranai, degalinės, viešbučiai, parduotuvės, lankytinos vietos ir daugelis kitų;
|
||||||
|
• Paieška pagal pavadinimą, adresą arba lankytinos vietos kategoriją;
|
||||||
|
• Navigacija su balso instrukcijomis pėstiesiems, dviratininkams ir motorinio transporto vairuotojams;
|
||||||
|
• Mėgstamų vietų įsiminimas vienu bakstelėjimu;
|
||||||
|
• „Vikipedijos“ straipsniai, prieinami neprisijungus prie interneto;
|
||||||
|
• Kelionių metro sluoksnis ir maršrutai;
|
||||||
|
• Trasų įrašymas;
|
||||||
|
• Žymių ir trasų eksportavimas ir importavimas KML, KMZ, GPX formatais;
|
||||||
|
• Tamsaus žemėlapio veiksena, skirta naudoti naktį;
|
||||||
|
• Galimybė papildyti žemėlapio duomenis visiems, naudojantis įtaisytuoju baziniu redaktoriumi.
|
||||||
|
|
||||||
|
<b>Laisvė yra čia</b>
|
||||||
|
Atraskite savo kelionę ir keliaukite po pasaulį, kuriame privatumas ir bendruomenė yra svarbiausia!
|
||||||
@@ -1 +1 @@
|
|||||||
Paprasta ir patogi navigacija – Turiningos kelionės – Vystoma bendruomenės
|
Paprasta ir patogi navigacija – Turiningesnės kelionės – Vystoma bendruomenės
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
• Dane OpenStreetMap z 9 grudnia
|
|
||||||
• Użycie motywów Material 3
|
|
||||||
• Obsługa gniazd ładowania w Edytorze OSM
|
|
||||||
• Dodane gniazda ładowania schuko/type-E
|
|
||||||
• Poprawiony ranking wyników wyszukiwania
|
|
||||||
• Dodane litewskie i łotewskie komunikaty głosowe
|
|
||||||
• Poprawiony rozmiar znaków drogowych
|
|
||||||
• Poziom powiększenia oparty na odległości do następnego manewru
|
|
||||||
• Zmieniona kolejność ustawień
|
|
||||||
Więcej szczegółów na codeberg.org/comaps/comaps/releases
|
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
• Dados OpenStreetMap atualizados em 9 de dezembro
|
• Dados OSM de 17/12
|
||||||
• Uso do estilo Material 3
|
• Servidor de download de mapas configurável
|
||||||
• Suporte para tomadas de carregamento no Editor OSM
|
• Adição de informações sobre mapas desatualizados e um botão de atualização ao cartão de informações do local selecionado
|
||||||
• Adição de tomadas de carregamento Schuko/Tipo E
|
• Evita o uso de corredores de estacionamento para roteamento
|
||||||
• Melhoria na classificação dos resultados de busca
|
• Formato dos botões de zoom alterado
|
||||||
• Adição dos idiomas letão e lituano nas orientações por voz
|
• Sinônimos de busca em francês aprimorados
|
||||||
• Melhoria no tamanho das indicações de direção
|
• Editor OSM: verificação do limite de comprimento das tags do OSM na validação de valores
|
||||||
• Nível de zoom baseado em distância até a próxima curva
|
|
||||||
• Configurações reordenadas
|
|
||||||
Mais detalhes em codeberg.org/comaps/comaps/releases
|
Mais detalhes em codeberg.org/comaps/comaps/releases
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
• Карты OpenStreetMap от 17 декабря
|
||||||
|
• Возможность настройки сервера для скачивания карт
|
||||||
|
• Добавлена информация об устаревании карт и кнопка обновления (при выборе места на карте)
|
||||||
|
• Парковочные проезды больше не используются для транзитной маршрутизации
|
||||||
|
• Изменены кнопки масштабирования карты
|
||||||
|
• На карту добавлены ирригационные гидранты
|
||||||
|
• Редактор OSM: проверка максимальной длины OSM тегов
|
||||||
|
Подробнее на codeberg.org/comaps/comaps/releases
|
||||||
@@ -1,31 +1,31 @@
|
|||||||
Brezplačno in odprtokodno zemljevidno orodje, ki ga vodi skupnost, temelji na podatkih OpenStreetMap in je okrepljena s predanostjo transparentnosti, zasebnosti in nedobičkonosnosti. CoMaps je izpeljanka OrganicMaps, ta pa je izpeljanka Maps.ME.
|
Brezplačno in odprtokodno zemljevidno orodje, ki ga vodi skupnost, temelji na podatkih OpenStreetMap in je okrepljena s predanostjo transparentnosti, zasebnosti in nepridobitnosti. CoMaps je izpeljanka OrganicMaps, ta pa je izpeljanka Maps.ME.
|
||||||
|
|
||||||
Preverite si o razlogih za ta projekt in njegovi usmerjenosti na <b><i>codeberg.org/comaps</i></b>.
|
Preberite si o razlogih za ta projekt in njegovi usmerjenosti na <b><i>codeberg.org/comaps</i></b>.
|
||||||
Pridružite se skupnosti in pomagajte narediti najboljše zemljevidno orodje
|
Pridružite se skupnosti in pomagajte narediti najboljše zemljevidno orodje
|
||||||
• Uporabljajte orodje in širite glas o njem
|
• Uporabljajte orodje in širite glas o njem
|
||||||
• Dajajte povratne informacije in poročajte o napakah
|
• Dajajte povratne informacije in poročajte o napakah
|
||||||
• Posodabljajte podatke zemljevida v tem orodju ali na spletni strani OpenStreetMap
|
• Posodabljajte podatke zemljevida v tem orodju ali na spletni strani OpenStreetMap
|
||||||
|
|
||||||
‣ <b>Osredotočeno na uporabo brez povezave</b>: Načrtujte in se usmerjajte na vašem potovanju v tujini vrez potrebe po mobilnih podatkih, iščite vmesne točke potocanja ko ste na daljšem pohodu ipd. Vse zmogljivosti orodja so zasnovane za delo brez povezave.
|
‣ <b>Osredotočeno na uporabo brez povezave</b>: Načrtujte in se usmerjajte na vašem potovanju v tujini vrez potrebe po mobilnih podatkih, iščite vmesne točke potovanja ko ste na daljšem pohodu ipd. Vse zmogljivosti orodja so zasnovane za delo brez povezave.
|
||||||
‣ <b>Spoštovanje zasebnosti</b>: orodje je zasnovano z mislijo na zasebnost – ne prepoznava oseb, ne sledi in ne zbira osebnih podatkov. Brez oglasov.
|
‣ <b>Spoštovanje zasebnosti</b>: orodje je zasnovano z mislijo na zasebnost – ne prepoznava oseb, ne sledi in ne zbira osebnih podatkov. Brez oglasov.
|
||||||
‣ <b>Preprosto in dodelano</b>: nujne zmogljivosti, enostavne za uporabo, ki preprosto delujejo.
|
‣ <b>Preprosto in dodelano</b>: nujne zmogljivosti, enostavne za uporabo, ki preprosto delujejo.
|
||||||
‣ <b>Prihrani vašo baterijo in prostor.</b>: ne izčrpava vaše baterije kakor druga usmerjevalna orodja. Strnjeni zemljevidi prihranijo dragocen prostor na vašem telefonu.
|
‣ <b>Prihrani vašo baterijo in prostor.</b>: ne izčrpava vaše baterije kakor druga usmerjevalna orodja. Strnjeni zemljevidi prihranijo dragocen prostor na vašem telefonu.
|
||||||
‣ <b>Brezplačno in ustvarjeno v skupnosti</b>: ljudje kot ste vi pomagajo ustvarjati to orodje, tako da dodajajo kraje na OpenStreetMap, preizkušajo in dajejo povratne informacije o zmogljivostih in prispevajo svoje razvijalske sposobnosti in sredstva.
|
‣ <b>Brezplačno in ustvarjeno v skupnosti</b>: ljudje kot ste vi pomagajo ustvarjati to orodje, tako da dodajajo kraje na OpenStreetMap, preizkušajo in dajejo povratne informacije o zmogljivostih in prispevajo svoje razvijalske sposobnosti in sredstva.
|
||||||
‣ <b>Odprto in transparentno odločanje in finance, nedobičkonosno in popolnoma odprtokodno.</b>
|
‣ <b>Odprto in transparentno odločanje in finance, nepridobitno in popolnoma odprtokodno.</b>
|
||||||
|
|
||||||
<b>Glavne zmogljivosti</b>:
|
<b>Glavne zmogljivosti</b>:
|
||||||
• Prenosljivi podrobni zemljevidi s kraji, ki na Googlovoh zemljevidih niso na voljo.
|
• Prenosljivi podrobni zemljevidi s kraji, ki na Googlovih zemljevidih niso na voljo.
|
||||||
• Prikaz za dejavnosti na prostem s poudarjenimi pohodniškimi potmi, tabornimi prostori, vodnimi viri, vrhovi, plastnicami itd.
|
• Prikaz za dejavnosti na prostem s poudarjenimi pohodniškimi potmi, tabornimi prostori, vodnimi viri, vrhovi, plastnicami itd.
|
||||||
• Pešpoti in kolesarke poti
|
• Pešpoti in kolesarke poti
|
||||||
• Kraji zanimanja, npr. restavracije, bencinske črpalke, hoteli, trgovine, znamenitosti in mnogo več
|
• Kraji zanimanja, npr. restavracije, bencinske črpalke, hoteli, trgovine, znamenitosti in mnogo več
|
||||||
• Iščite po imenu, hišnemu naslovu ali po vrsti
|
• Iščite po imenu, hišnemu naslovu ali po vrsti
|
||||||
• Usmerjanje z glasovnimi obvestili za hojo, kolesarjenje ali vožnjo avtomobila.
|
• Usmerjanje z glasovnimi navodili za hojo, kolesarjenje ali vožnjo avtomobila.
|
||||||
• Zaznamujte svoje najljubše kraje s preprostim dotikom
|
• Zaznamujte svoje najljubše kraje s preprostim dotikom
|
||||||
• Wikipedijini članki brez povezave
|
• Wikipedijini članki brez povezave
|
||||||
• Prometna plast podzemne železnice z usmerjanjem
|
• Prometna plast podzemne železnice z usmerjanjem
|
||||||
• Izvozite ali uvozite zaznamke in sledi v oblikah KML, KMZ, GPX
|
• Izvozite ali uvozite zaznamke in sledi v oblikah KML, KMZ, GPX
|
||||||
• Temni prikaz za uporabo ponoči
|
• Temni prikaz za uporabo ponoči
|
||||||
• Izboljšajtw podatke zemljevida za vse z uporabo vgrajenega urejevalnika
|
• Izboljšajte podatke zemljevida za vse z uporabo vgrajenega urejevalnika
|
||||||
|
|
||||||
<b>Svoboda je tu</b>
|
<b>Svoboda je tu</b>
|
||||||
Odkijte več o vašem potovanju, usmerjajte se po svetu s poudarkom na zasebnosti in skupnostnem delovanju!
|
Odkijte več o vašem potovanju, usmerjajte se po svetu s poudarkom na zasebnosti in skupnostnem delovanju!
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Enostavno usmerjanje – Odkrij več o svojem potovanju – Podprto v skupnosti
|
Enostavno usmerjanje – Odkrijte več o svojem potovanju – Podprto v skupnosti
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
CoMaps–Hodi, kolesari, vozi brez povezave, zasebno
|
CoMaps – hodi in vozi brez povezave, zasebno
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Eine von der Community betriebene, kostenlose Open-Source Karten App, die auf Op
|
|||||||
Werde Teil der Community und hilf mit, die beste Karten-App zu entwickeln
|
Werde Teil der Community und hilf mit, die beste Karten-App zu entwickeln
|
||||||
• Nutze die App und erzähle anderen davon
|
• Nutze die App und erzähle anderen davon
|
||||||
• Gib Feedback und melde Probleme
|
• Gib Feedback und melde Probleme
|
||||||
• Aktualisiere Kartendaten in der App oder auf der OpenStreetMap Website
|
• Aktualisiere Kartendaten in der App oder auf der OpenStreetMap-Webseite
|
||||||
|
|
||||||
<i>Dein Feedback und deine 5-Sterne-Bewertung sind die beste Unterstützung für uns!</i>
|
<i>Dein Feedback und deine 5-Sterne-Bewertung sind die beste Unterstützung für uns!</i>
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ Werde Teil der Community und hilf mit, die beste Karten-App zu entwickeln
|
|||||||
‣ <b>Datenschutz ist uns wichtig!</b>: Die App wurde mit Fokus auf Privatsphäre entwickelt – kein Tracking, keine Erfassung persönlicher Daten, keine Werbung.
|
‣ <b>Datenschutz ist uns wichtig!</b>: Die App wurde mit Fokus auf Privatsphäre entwickelt – kein Tracking, keine Erfassung persönlicher Daten, keine Werbung.
|
||||||
‣ <b>Spart Akku und Speicherplatz</b>: Verbraucht nicht unnötig Akku wie andere Navi-Apps. Kompakte Karten sparen Speicherplatz auf Deinem Gerät.
|
‣ <b>Spart Akku und Speicherplatz</b>: Verbraucht nicht unnötig Akku wie andere Navi-Apps. Kompakte Karten sparen Speicherplatz auf Deinem Gerät.
|
||||||
‣ <b>Kostenlos und von der Community entwickelt</b>: Menschen wie du haben geholfen, die App zu entwickeln – durch das Hinzufügen von Orten zu OpenStreetMap, Testen von neuen Funktionen, Softwareentwicklung oder Spenden.
|
‣ <b>Kostenlos und von der Community entwickelt</b>: Menschen wie du haben geholfen, die App zu entwickeln – durch das Hinzufügen von Orten zu OpenStreetMap, Testen von neuen Funktionen, Softwareentwicklung oder Spenden.
|
||||||
‣ <b>Offen und transparent bei Entscheidungen und Finanzen, gemeinnützig und vollständig Open Source</b>
|
‣ <b>Offen und transparent bei Entscheidungen und Finanzen, gemeinnützig und vollständig Open Source.</b>
|
||||||
|
|
||||||
<b>Hauptfunktionen</b>:
|
<b>Hauptfunktionen</b>:
|
||||||
• Detaillierte, herunterladbare Karten mit Orten, die bei Google Maps oft fehlen
|
• Detaillierte, herunterladbare Karten mit Orten, die bei Google Maps oft fehlen
|
||||||
@@ -24,13 +24,13 @@ Werde Teil der Community und hilf mit, die beste Karten-App zu entwickeln
|
|||||||
• Lesezeichen mit einem einzigen Tippen speichern
|
• Lesezeichen mit einem einzigen Tippen speichern
|
||||||
• Offline verfügbare Wikipedia-Artikel
|
• Offline verfügbare Wikipedia-Artikel
|
||||||
• U- und S-Bahn-Netze
|
• U- und S-Bahn-Netze
|
||||||
• Aufzeichnen von GPS Tracks
|
• Aufzeichnen von GPS-Tracks
|
||||||
• Import und Export von Favoriten und Routen im KML-, KMZ- oder GPX-Format
|
• Import und Export von Favoriten und Routen im KML-, KMZ- oder GPX-Format
|
||||||
• Dunkler Modus für die Nutzung bei Nacht
|
• Dunkler Modus für die Nutzung bei Nacht
|
||||||
• Kartenbearbeitung direkt in der App mit einem einfachen Editor
|
• Kartenbearbeitung direkt in der App mit einem einfachen Editor
|
||||||
• Unterstützung für Android Auto
|
• Unterstützung für Android Auto
|
||||||
|
|
||||||
Bitte melde Probleme, schlage neue Funktionen vor und werde Teil der Community auf unserer Website: <b><i>comaps.app</i></b>
|
Bitte melde Probleme, schlage neue Funktionen vor und werde Teil der Community auf unserer Website: <b><i>comaps.app/de/</i></b>
|
||||||
|
|
||||||
<b>Entdecke die Unabhängigkeit</b>
|
<b>Freiheit beginnt hier</b>
|
||||||
Entdecke deine Reise – navigiere in der Welt mit Datenschutz!
|
Entdecke deine Reise, wobei Datenschutz und Gemeinschaft im Vordergrund stehen!
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Einfache Navigation - Entdecken Sie mehr von Ihrer Reise - Community-Entwickelt
|
Leichte Navigation – Erlebe mehr von deiner Reise – Community-unterstützt
|
||||||
|
|||||||
36
android/app/src/google/play/listings/lt/full-description.txt
Normal file
36
android/app/src/google/play/listings/lt/full-description.txt
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
Bendruomenės vystoma nemokama atvirojo kodo žemėlapių programa, pagrįsta „OpenStreetMap“ duomenimis ir sustiprinta įsipareigojimu užtikrinti skaidrumą, privatumą ir pelno nesiekimą.
|
||||||
|
|
||||||
|
Prisijunkite prie bendruomenės ir padėkite sukurti geriausią žemėlapių programą
|
||||||
|
• Naudokitės programa ir paskleiskite žinią apie ją
|
||||||
|
• Teikite atsiliepimus ir praneškite apie problemas
|
||||||
|
• Atnaujinkite žemėlapių duomenis programoje arba „OpenStreetMap“ svetainėje
|
||||||
|
|
||||||
|
<i>Jūsų atsiliepimai ir 5 žvaigždučių vertinimai yra geriausias palaikymas mums!</i>
|
||||||
|
|
||||||
|
‣ <b>Paprasta ir išbaigta</b>: esminės, lengvai naudojamos funkcijos, kurios tiesiog veikia.
|
||||||
|
‣ <b>Skirta naudoti neprisijungus prie interneto</b>: planuokite maršrutus ir keliaukite užsienyje be mobiliojo ryšio, ieškokite kelionės taškų tolimuose žygiuose ir pan. Visos programos funkcijos yra pritaikytos veikti be interneto ryšio.
|
||||||
|
‣ <b>Gerbia privatumą</b>: programėlė sukurta, teikiant prioritetą privatumui: neidentifikuoja žmonių, neseka ir nerenka asmeninės informacijos. Be reklamų.
|
||||||
|
‣ <b>Taupo bateriją ir vietą</b>: neišsekina baterijos kaip kitos navigacijos programos. Kompaktiški žemėlapiai tausoja vietą jūsų telefone.
|
||||||
|
‣ <b>Nemokama ir kuriama bendruomenės</b>: paprasti žmonės – kaip jūs – padėjo sukurti šią programą, pildydami „OpenStreetMap“ žemėlapį, išbandydami ir pateikdami atsiliepimus apie funkcijas bei prisidėdami savo programavimo įgūdžiais ir pinigais.
|
||||||
|
‣ <b>Atviras ir skaidrus sprendimų priėmimas ir finansai, ne pelno siekianti ir visiškai atviro kodo programa.</b>
|
||||||
|
|
||||||
|
<b>Pagrindinės funkcijos</b>:
|
||||||
|
• Atsisiunčiami išsamūs žemėlapiai su vietomis, kurių nėra „Google Maps“;
|
||||||
|
• Žygių pėsčiomis veiksena su pažymėtais pėsčiųjų takais, stovyklavietėmis, vandens šaltiniais, kalnų viršūnėmis, reljefo linijomis ir kt.;
|
||||||
|
• Pėsčiųjų ir dviračių takai;
|
||||||
|
• Potencialūs kelionės taškai, kaip antai restoranai, degalinės, viešbučiai, parduotuvės, lankytinos vietos ir daugelis kitų;
|
||||||
|
• Paieška pagal pavadinimą, adresą arba lankytinos vietos kategoriją;
|
||||||
|
• Navigacija su balso instrukcijomis pėstiesiems, dviratininkams ir motorinio transporto vairuotojams;
|
||||||
|
• Mėgstamų vietų įsiminimas vienu bakstelėjimu;
|
||||||
|
• „Vikipedijos“ straipsniai, prieinami neprisijungus prie interneto;
|
||||||
|
• Kelionių metro sluoksnis ir maršrutai;
|
||||||
|
• Trasų įrašymas;
|
||||||
|
• Žymių ir trasų eksportavimas ir importavimas KML, KMZ, GPX formatais;
|
||||||
|
• Tamsaus žemėlapio veiksena, skirta naudoti naktį;
|
||||||
|
• Galimybė papildyti žemėlapio duomenis visiems, naudojantis įtaisytuoju baziniu redaktoriumi;
|
||||||
|
• „Android Auto“ palaikymas.
|
||||||
|
|
||||||
|
Praneškite apie programos problemas, siūlykite idėjas ir prisijunkite prie mūsų bendruomenės svetainėje <b><i>comaps.app</i></b>.
|
||||||
|
|
||||||
|
<b>Laisvė yra čia</b>
|
||||||
|
Atraskite savo kelionę ir keliaukite po pasaulį, kuriame privatumas ir bendruomenė yra svarbiausia!
|
||||||
@@ -1 +1 @@
|
|||||||
Paprasta ir patogi navigacija – Turiningos kelionės – Vystoma bendruomenės
|
Paprasta ir patogi navigacija – Turiningesnės kelionės – Vystoma bendruomenės
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Enostavno usmerjanje – Odkrij več o svojem potovanju – Podprto v skupnosti
|
Enostavno usmerjanje – Odkrijte več o svojem potovanju – Podprto v skupnosti
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
CoMaps - Usmerjajte zasebno
|
CoMaps - Usmerjajte se zasebno
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
|||||||
import com.github.mikephil.charting.highlight.Highlight;
|
import com.github.mikephil.charting.highlight.Highlight;
|
||||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import android.location.Location;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
@@ -25,7 +26,15 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
|
|
||||||
|
import com.google.android.material.button.MaterialButton;
|
||||||
|
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import app.organicmaps.base.BaseMwmFragmentActivity;
|
import app.organicmaps.base.BaseMwmFragmentActivity;
|
||||||
|
import app.organicmaps.dialog.CustomMapServerDialog;
|
||||||
import app.organicmaps.downloader.MapManagerHelper;
|
import app.organicmaps.downloader.MapManagerHelper;
|
||||||
import app.organicmaps.intent.Factory;
|
import app.organicmaps.intent.Factory;
|
||||||
import app.organicmaps.sdk.Framework;
|
import app.organicmaps.sdk.Framework;
|
||||||
@@ -38,11 +47,7 @@ import app.organicmaps.sdk.util.StringUtils;
|
|||||||
import app.organicmaps.util.UiUtils;
|
import app.organicmaps.util.UiUtils;
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
||||||
import com.google.android.material.button.MaterialButton;
|
|
||||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
||||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -54,6 +59,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
private MaterialTextView mTvMessage;
|
private MaterialTextView mTvMessage;
|
||||||
private LinearProgressIndicator mProgress;
|
private LinearProgressIndicator mProgress;
|
||||||
private MaterialButton mBtnDownload;
|
private MaterialButton mBtnDownload;
|
||||||
|
private MaterialButton mBtnAdvanced;
|
||||||
private MaterialCheckBox mChbDownloadCountry;
|
private MaterialCheckBox mChbDownloadCountry;
|
||||||
|
|
||||||
private String mCurrentCountry;
|
private String mCurrentCountry;
|
||||||
@@ -253,7 +259,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
mProgress.setMax(bytes);
|
mProgress.setMax(bytes);
|
||||||
// Start progress at 1% according to M3 guidelines
|
// Start progress at 1% according to M3 guidelines
|
||||||
mProgress.setProgressCompat(bytes / 100, true);
|
mProgress.setProgressCompat(bytes/100, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
finishFilesDownload(bytes);
|
finishFilesDownload(bytes);
|
||||||
@@ -267,6 +273,14 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
mProgress = findViewById(R.id.progressbar);
|
mProgress = findViewById(R.id.progressbar);
|
||||||
mBtnDownload = findViewById(R.id.btn_download_resources);
|
mBtnDownload = findViewById(R.id.btn_download_resources);
|
||||||
mChbDownloadCountry = findViewById(R.id.chb_download_country);
|
mChbDownloadCountry = findViewById(R.id.chb_download_country);
|
||||||
|
mBtnAdvanced = findViewById(R.id.btn_advanced);
|
||||||
|
|
||||||
|
mBtnAdvanced.setOnClickListener(v -> {
|
||||||
|
CustomMapServerDialog.show(this, url -> {
|
||||||
|
prepareFilesDownload(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
mBtnAdvanced.setEnabled(true);
|
||||||
|
|
||||||
mBtnListeners = new View.OnClickListener[BTN_COUNT];
|
mBtnListeners = new View.OnClickListener[BTN_COUNT];
|
||||||
mBtnNames = new String[BTN_COUNT];
|
mBtnNames = new String[BTN_COUNT];
|
||||||
@@ -291,6 +305,11 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
{
|
{
|
||||||
mBtnDownload.setOnClickListener(mBtnListeners[action]);
|
mBtnDownload.setOnClickListener(mBtnListeners[action]);
|
||||||
mBtnDownload.setText(mBtnNames[action]);
|
mBtnDownload.setText(mBtnNames[action]);
|
||||||
|
|
||||||
|
// Allow changing server only when idle or after an error.
|
||||||
|
boolean advancedEnabled = (action == DOWNLOAD || action == TRY_AGAIN || action == RESUME);
|
||||||
|
mBtnAdvanced.setEnabled(advancedEnabled);
|
||||||
|
mBtnAdvanced.setAlpha(advancedEnabled ? 1f : 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doDownload()
|
private void doDownload()
|
||||||
@@ -359,6 +378,9 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
private void finishFilesDownload(int result)
|
private void finishFilesDownload(int result)
|
||||||
{
|
{
|
||||||
|
mBtnAdvanced.setEnabled(true);
|
||||||
|
mBtnAdvanced.setAlpha(1f);
|
||||||
|
|
||||||
if (result == ERR_NO_MORE_FILES)
|
if (result == ERR_NO_MORE_FILES)
|
||||||
{
|
{
|
||||||
// World and WorldCoasts has been downloaded, we should register maps again to correctly add them to the model.
|
// World and WorldCoasts has been downloaded, we should register maps again to correctly add them to the model.
|
||||||
@@ -372,7 +394,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString));
|
mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString));
|
||||||
mProgress.setMax((int) item.totalSize);
|
mProgress.setMax((int) item.totalSize);
|
||||||
// Start progress at 1% according to M3 guidelines
|
// Start progress at 1% according to M3 guidelines
|
||||||
mProgress.setProgressCompat((int) (item.totalSize / 100), true);
|
mProgress.setProgressCompat((int) (item.totalSize/100), true);
|
||||||
|
|
||||||
mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener);
|
mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener);
|
||||||
MapManagerHelper.startDownload(mCurrentCountry);
|
MapManagerHelper.startDownload(mCurrentCountry);
|
||||||
@@ -424,16 +446,20 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
default -> throw new AssertionError("Unexpected result code = " + result);
|
default -> throw new AssertionError("Unexpected result code = " + result);
|
||||||
};
|
};
|
||||||
|
|
||||||
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
mAlertDialog = new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(titleId)
|
.setTitle(titleId)
|
||||||
.setMessage(messageId)
|
.setMessage(messageId)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setOnCancelListener((dialog) -> setAction(PAUSE))
|
.setOnCancelListener((dialog) -> setAction(RESUME))
|
||||||
.setPositiveButton(R.string.try_again,
|
.setPositiveButton(R.string.try_again,
|
||||||
(dialog, which) -> {
|
(dialog, which) -> {
|
||||||
setAction(TRY_AGAIN);
|
setAction(TRY_AGAIN);
|
||||||
onTryAgainClicked();
|
onTryAgainClicked();
|
||||||
})
|
})
|
||||||
|
.setNegativeButton(R.string.cancel,
|
||||||
|
(dialog, which) -> {
|
||||||
|
setAction(RESUME);
|
||||||
|
})
|
||||||
.setOnDismissListener(dialog -> mAlertDialog = null)
|
.setOnDismissListener(dialog -> mAlertDialog = null)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
dismissLocationErrorDialog();
|
dismissLocationErrorDialog();
|
||||||
mLocationErrorDialog = new MaterialAlertDialogBuilder(MwmActivity.this, R.style.MwmTheme_AlertDialog)
|
mLocationErrorDialog = new MaterialAlertDialogBuilder(MwmActivity.this)
|
||||||
.setMessage(R.string.unknown_current_position)
|
.setMessage(R.string.unknown_current_position)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
@@ -655,7 +655,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
dismissAlertDialog();
|
dismissAlertDialog();
|
||||||
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
mAlertDialog = new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.message_invalid_feature_position)
|
.setTitle(R.string.message_invalid_feature_position)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.setOnDismissListener(dialog -> mAlertDialog = null)
|
.setOnDismissListener(dialog -> mAlertDialog = null)
|
||||||
@@ -1155,7 +1155,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
if (type == IsolinesState.EXPIREDDATA)
|
if (type == IsolinesState.EXPIREDDATA)
|
||||||
{
|
{
|
||||||
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
mAlertDialog = new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.downloader_update_maps)
|
.setTitle(R.string.downloader_update_maps)
|
||||||
.setMessage(R.string.isolines_activation_error_dialog)
|
.setMessage(R.string.isolines_activation_error_dialog)
|
||||||
.setPositiveButton(
|
.setPositiveButton(
|
||||||
@@ -1774,7 +1774,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
{
|
{
|
||||||
dismissAlertDialog();
|
dismissAlertDialog();
|
||||||
mAlertDialog =
|
mAlertDialog =
|
||||||
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.unable_to_calc_alert_title)
|
.setTitle(R.string.unable_to_calc_alert_title)
|
||||||
.setMessage(R.string.unable_to_calc_alert_subtitle)
|
.setMessage(R.string.unable_to_calc_alert_subtitle)
|
||||||
.setPositiveButton(R.string.settings,
|
.setPositiveButton(R.string.settings,
|
||||||
@@ -1797,7 +1797,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
builder.append(getString(resId)).append("\n\n");
|
builder.append(getString(resId)).append("\n\n");
|
||||||
|
|
||||||
dismissAlertDialog();
|
dismissAlertDialog();
|
||||||
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
mAlertDialog = new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.dialog_routing_disclaimer_title)
|
.setTitle(R.string.dialog_routing_disclaimer_title)
|
||||||
.setMessage(builder.toString())
|
.setMessage(builder.toString())
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
@@ -1846,7 +1846,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
final MapObject endPoint = Objects.requireNonNull(controller.getEndPoint());
|
final MapObject endPoint = Objects.requireNonNull(controller.getEndPoint());
|
||||||
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.p2p_only_from_current)
|
.setTitle(R.string.p2p_only_from_current)
|
||||||
.setMessage(R.string.p2p_reroute_from_current)
|
.setMessage(R.string.p2p_reroute_from_current)
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
@@ -2040,7 +2040,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
{
|
{
|
||||||
mPreciseLocationDialogShown = true;
|
mPreciseLocationDialogShown = true;
|
||||||
final MaterialAlertDialogBuilder builder =
|
final MaterialAlertDialogBuilder builder =
|
||||||
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle("⚠ " + getString(R.string.limited_accuracy))
|
.setTitle("⚠ " + getString(R.string.limited_accuracy))
|
||||||
.setMessage(R.string.precise_location_is_disabled_long_text)
|
.setMessage(R.string.precise_location_is_disabled_long_text)
|
||||||
.setNegativeButton(R.string.close, (dialog, which) -> dialog.dismiss())
|
.setNegativeButton(R.string.close, (dialog, which) -> dialog.dismiss())
|
||||||
@@ -2074,7 +2074,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLocationErrorDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
mLocationErrorDialog = new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.enable_location_services)
|
.setTitle(R.string.enable_location_services)
|
||||||
.setMessage(R.string.location_is_disabled_long_text)
|
.setMessage(R.string.location_is_disabled_long_text)
|
||||||
.setOnDismissListener(dialog -> mLocationErrorDialog = null)
|
.setOnDismissListener(dialog -> mLocationErrorDialog = null)
|
||||||
@@ -2167,7 +2167,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.enable_location_services)
|
.setTitle(R.string.enable_location_services)
|
||||||
.setMessage(R.string.location_is_disabled_long_text)
|
.setMessage(R.string.location_is_disabled_long_text)
|
||||||
.setOnDismissListener(dialog -> mLocationErrorDialog = null)
|
.setOnDismissListener(dialog -> mLocationErrorDialog = null)
|
||||||
@@ -2253,7 +2253,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
dismissAlertDialog();
|
dismissAlertDialog();
|
||||||
final MaterialAlertDialogBuilder builder =
|
final MaterialAlertDialogBuilder builder =
|
||||||
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.current_location_unknown_error_title)
|
.setTitle(R.string.current_location_unknown_error_title)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setMessage(R.string.power_save_dialog_summary)
|
.setMessage(R.string.power_save_dialog_summary)
|
||||||
@@ -2278,7 +2278,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
{
|
{
|
||||||
dismissAlertDialog();
|
dismissAlertDialog();
|
||||||
mAlertDialog =
|
mAlertDialog =
|
||||||
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.load_kmz_title)
|
.setTitle(R.string.load_kmz_title)
|
||||||
.setMessage(getString(R.string.unknown_file_type, uri))
|
.setMessage(getString(R.string.unknown_file_type, uri))
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
@@ -2295,7 +2295,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
{
|
{
|
||||||
dismissAlertDialog();
|
dismissAlertDialog();
|
||||||
mAlertDialog =
|
mAlertDialog =
|
||||||
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.load_kmz_title)
|
.setTitle(R.string.load_kmz_title)
|
||||||
.setMessage(getString(R.string.failed_to_open_file, uri, error))
|
.setMessage(getString(R.string.failed_to_open_file, uri, error))
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
@@ -2317,7 +2317,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
public void onBookmarksFileImportFailed()
|
public void onBookmarksFileImportFailed()
|
||||||
{
|
{
|
||||||
dismissAlertDialog();
|
dismissAlertDialog();
|
||||||
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
mAlertDialog = new MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.load_kmz_title)
|
.setTitle(R.string.load_kmz_title)
|
||||||
.setMessage(R.string.load_kmz_failed)
|
.setMessage(R.string.load_kmz_failed)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
@@ -2578,7 +2578,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
private void reportUnsupported()
|
private void reportUnsupported()
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(this)
|
||||||
.setMessage(R.string.unsupported_phone)
|
.setMessage(R.string.unsupported_phone)
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setPositiveButton(R.string.close, (dlg, which) -> this.moveTaskToBack(true))
|
.setPositiveButton(R.string.close, (dlg, which) -> this.moveTaskToBack(true))
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public class SplashActivity extends AppCompatActivity
|
|||||||
private void showFatalErrorDialog(@StringRes int titleId, @StringRes int messageId, Exception error)
|
private void showFatalErrorDialog(@StringRes int titleId, @StringRes int messageId, Exception error)
|
||||||
{
|
{
|
||||||
mCanceled = true;
|
mCanceled = true;
|
||||||
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_M3_AlertDialog)
|
||||||
.setTitle(titleId)
|
.setTitle(titleId)
|
||||||
.setMessage(messageId)
|
.setMessage(messageId)
|
||||||
.setPositiveButton(
|
.setPositiveButton(
|
||||||
|
|||||||
@@ -38,8 +38,7 @@ public class OsmUploadWork extends Worker
|
|||||||
{
|
{
|
||||||
final Constraints c = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
|
final Constraints c = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
|
||||||
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c);
|
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
{
|
|
||||||
builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST);
|
builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST);
|
||||||
}
|
}
|
||||||
final OneTimeWorkRequest wr = builder.build();
|
final OneTimeWorkRequest wr = builder.build();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.documentfile.provider.DocumentFile;
|
import androidx.documentfile.provider.DocumentFile;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import androidx.fragment.app.DialogFragment;
|
|||||||
|
|
||||||
public class BaseMwmDialogFragment extends DialogFragment
|
public class BaseMwmDialogFragment extends DialogFragment
|
||||||
{
|
{
|
||||||
|
|
||||||
protected int getStyle()
|
protected int getStyle()
|
||||||
{
|
{
|
||||||
return STYLE_NORMAL;
|
return STYLE_NORMAL;
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment
|
|||||||
@NonNull
|
@NonNull
|
||||||
private TextInputEditText mEditDescView;
|
private TextInputEditText mEditDescView;
|
||||||
|
|
||||||
|
@SuppressWarnings("NullableProblems")
|
||||||
|
@NonNull
|
||||||
|
private TextInputLayout mEditCategoryNameLayout;
|
||||||
|
|
||||||
@SuppressWarnings("NullableProblems")
|
@SuppressWarnings("NullableProblems")
|
||||||
@NonNull
|
@NonNull
|
||||||
private TextInputEditText mEditCategoryNameView;
|
private TextInputEditText mEditCategoryNameView;
|
||||||
@@ -61,8 +65,8 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment
|
|||||||
private void initViews(@NonNull View root)
|
private void initViews(@NonNull View root)
|
||||||
{
|
{
|
||||||
mEditCategoryNameView = root.findViewById(R.id.edit_list_name_view);
|
mEditCategoryNameView = root.findViewById(R.id.edit_list_name_view);
|
||||||
TextInputLayout clearNameBtn = root.findViewById(R.id.edit_list_name_input);
|
mEditCategoryNameLayout = root.findViewById(R.id.edit_list_name_input);
|
||||||
clearNameBtn.setEndIconOnClickListener(v -> clearAndFocus(mEditCategoryNameView));
|
mEditCategoryNameLayout.setEndIconOnClickListener(v -> clearAndFocus(mEditCategoryNameView));
|
||||||
mEditCategoryNameView.setText(mCategory.getName());
|
mEditCategoryNameView.setText(mCategory.getName());
|
||||||
InputFilter[] f = {new InputFilter.LengthFilter(TEXT_LENGTH_LIMIT)};
|
InputFilter[] f = {new InputFilter.LengthFilter(TEXT_LENGTH_LIMIT)};
|
||||||
mEditCategoryNameView.setFilters(f);
|
mEditCategoryNameView.setFilters(f);
|
||||||
@@ -75,7 +79,26 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment
|
|||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||||
{
|
{
|
||||||
clearNameBtn.setEndIconVisible(charSequence.length() > 0);
|
if (charSequence.length() > 0)
|
||||||
|
{
|
||||||
|
mEditCategoryNameLayout.setEndIconVisible(true);
|
||||||
|
mEditCategoryNameLayout.setErrorEnabled(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mEditCategoryNameLayout.setEndIconVisible(false);
|
||||||
|
mEditCategoryNameLayout.setErrorEnabled(true);
|
||||||
|
mEditCategoryNameLayout.setError(getString(R.string.bookmarks_error_title_empty_list_name));
|
||||||
|
}
|
||||||
|
if (BookmarkManager.INSTANCE.isUsedCategoryName(charSequence.toString()) && !TextUtils.equals(charSequence.toString(), mCategory.getName()))
|
||||||
|
{
|
||||||
|
mEditCategoryNameLayout.setErrorEnabled(true);
|
||||||
|
mEditCategoryNameLayout.setError(getString(R.string.bookmarks_error_title_list_name_already_taken));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mEditCategoryNameLayout.setErrorEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -282,13 +282,11 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
{
|
{
|
||||||
if (isEmptySearchResults())
|
if (isEmptySearchResults())
|
||||||
{
|
{
|
||||||
requirePlaceholder().setContent(R.string.search_not_found, R.string.search_not_found_query,
|
requirePlaceholder().setContent(R.string.search_not_found, R.string.search_not_found_query, R.drawable.ic_search_fail);
|
||||||
R.drawable.ic_search_fail);
|
|
||||||
}
|
}
|
||||||
else if (isEmpty())
|
else if (isEmpty())
|
||||||
{
|
{
|
||||||
requirePlaceholder().setContent(R.string.bookmarks_empty_list_title, R.string.bookmarks_empty_list_message,
|
requirePlaceholder().setContent(R.string.bookmarks_empty_list_title, R.string.bookmarks_empty_list_message, R.drawable.ic_bookmarks);
|
||||||
R.drawable.ic_bookmarks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isEmptyRecycler = isEmpty() || isEmptySearchResults();
|
boolean isEmptyRecycler = isEmpty() || isEmptySearchResults();
|
||||||
|
|||||||
@@ -60,14 +60,14 @@ public enum BookmarksSharingHelper
|
|||||||
case BookmarkSharingResult.SUCCESS ->
|
case BookmarkSharingResult.SUCCESS ->
|
||||||
SharingUtils.shareBookmarkFile(context, launcher, result.getSharingPath(), result.getMimeType());
|
SharingUtils.shareBookmarkFile(context, launcher, result.getSharingPath(), result.getMimeType());
|
||||||
case BookmarkSharingResult.EMPTY_CATEGORY ->
|
case BookmarkSharingResult.EMPTY_CATEGORY ->
|
||||||
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(context)
|
||||||
.setTitle(R.string.bookmarks_error_title_share_empty)
|
.setTitle(R.string.bookmarks_error_title_share_empty)
|
||||||
.setMessage(R.string.bookmarks_error_message_share_empty)
|
.setMessage(R.string.bookmarks_error_message_share_empty)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show();
|
.show();
|
||||||
case BookmarkSharingResult.ARCHIVE_ERROR, BookmarkSharingResult.FILE_ERROR ->
|
case BookmarkSharingResult.ARCHIVE_ERROR, BookmarkSharingResult.FILE_ERROR ->
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(context)
|
||||||
.setTitle(R.string.dialog_routing_system_error)
|
.setTitle(R.string.dialog_routing_system_error)
|
||||||
.setMessage(R.string.bookmarks_error_message_share_general)
|
.setMessage(R.string.bookmarks_error_message_share_general)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import app.organicmaps.util.UiUtils;
|
|||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.widget.recycler.RecyclerClickListener;
|
import app.organicmaps.widget.recycler.RecyclerClickListener;
|
||||||
import app.organicmaps.widget.recycler.RecyclerLongClickListener;
|
import app.organicmaps.widget.recycler.RecyclerLongClickListener;
|
||||||
|
|
||||||
import com.google.android.material.button.MaterialButton;
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||||
import com.google.android.material.imageview.ShapeableImageView;
|
import com.google.android.material.imageview.ShapeableImageView;
|
||||||
@@ -457,12 +458,10 @@ public class Holders
|
|||||||
|
|
||||||
String formattedDesc = desc.replace("\n", "<br>");
|
String formattedDesc = desc.replace("\n", "<br>");
|
||||||
Spanned spannedDesc = Utils.fromHtml(formattedDesc);
|
Spanned spannedDesc = Utils.fromHtml(formattedDesc);
|
||||||
if (!TextUtils.isEmpty(spannedDesc))
|
if (!TextUtils.isEmpty(spannedDesc)) {
|
||||||
{
|
|
||||||
mDescText.setText(spannedDesc);
|
mDescText.setText(spannedDesc);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
mDescText.setText(R.string.list_description_empty);
|
mDescText.setText(R.string.list_description_empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ public final class IntentUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://developer.android.com/reference/androidx/car/app/CarContext#startCarApp(android.content.Intent)
|
// https://developer.android.com/reference/androidx/car/app/CarContext#startCarApp(android.content.Intent)
|
||||||
private static void processNavigationIntent(@NonNull CarContext carContext, @NonNull Renderer surfaceRenderer,
|
private static void processNavigationIntent(@NonNull CarContext carContext,
|
||||||
@NonNull Intent intent)
|
@NonNull Renderer surfaceRenderer, @NonNull Intent intent)
|
||||||
{
|
{
|
||||||
// TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during
|
// TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during
|
||||||
// navigation or route planning. Skip navigation intents during navigation
|
// navigation or route planning. Skip navigation intents during navigation
|
||||||
|
|||||||
@@ -85,8 +85,7 @@ public final class RoutingHelpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private static IconCompat createManeuverIcon(@NonNull final CarContext context, @NonNull CarDirection carDirection,
|
private static IconCompat createManeuverIcon(@NonNull final CarContext context, @NonNull CarDirection carDirection, int roundaboutExitNum)
|
||||||
int roundaboutExitNum)
|
|
||||||
{
|
{
|
||||||
if (!CarDirection.isRoundAbout(carDirection) || roundaboutExitNum == 0)
|
if (!CarDirection.isRoundAbout(carDirection) || roundaboutExitNum == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ public final class UiHelpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static ActionStrip createMapActionStrip(@NonNull CarContext context, @NonNull Renderer surfaceRenderer)
|
public static ActionStrip createMapActionStrip(@NonNull CarContext context,
|
||||||
|
@NonNull Renderer surfaceRenderer)
|
||||||
{
|
{
|
||||||
final CarIcon iconPlus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_plus)).build();
|
final CarIcon iconPlus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_plus)).build();
|
||||||
final CarIcon iconMinus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_minus)).build();
|
final CarIcon iconMinus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_minus)).build();
|
||||||
@@ -58,13 +59,15 @@ public final class UiHelpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static MapController createMapController(@NonNull CarContext context, @NonNull Renderer surfaceRenderer)
|
public static MapController createMapController(@NonNull CarContext context,
|
||||||
|
@NonNull Renderer surfaceRenderer)
|
||||||
{
|
{
|
||||||
return new MapController.Builder().setMapActionStrip(createMapActionStrip(context, surfaceRenderer)).build();
|
return new MapController.Builder().setMapActionStrip(createMapActionStrip(context, surfaceRenderer)).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull Renderer surfaceRenderer)
|
public static Action createSettingsAction(@NonNull BaseMapScreen mapScreen,
|
||||||
|
@NonNull Renderer surfaceRenderer)
|
||||||
{
|
{
|
||||||
return createSettingsAction(mapScreen, surfaceRenderer, null);
|
return createSettingsAction(mapScreen, surfaceRenderer, null);
|
||||||
}
|
}
|
||||||
@@ -78,7 +81,8 @@ public final class UiHelpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull Renderer surfaceRenderer,
|
private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen,
|
||||||
|
@NonNull Renderer surfaceRenderer,
|
||||||
@Nullable OnScreenResultListener onScreenResultListener)
|
@Nullable OnScreenResultListener onScreenResultListener)
|
||||||
{
|
{
|
||||||
final CarContext context = mapScreen.getCarContext();
|
final CarContext context = mapScreen.getCarContext();
|
||||||
@@ -119,7 +123,8 @@ public final class UiHelpers
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
final Row.Builder builder = new Row.Builder();
|
final Row.Builder builder = new Row.Builder();
|
||||||
builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_opening_hours)).build());
|
builder.setImage(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_opening_hours)).build());
|
||||||
|
|
||||||
if (isEmptyTT)
|
if (isEmptyTT)
|
||||||
builder.setTitle(ohStr);
|
builder.setTitle(ohStr);
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package app.organicmaps.dialog;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
|
||||||
|
import app.organicmaps.R;
|
||||||
|
import app.organicmaps.sdk.Framework;
|
||||||
|
|
||||||
|
public final class CustomMapServerDialog
|
||||||
|
{
|
||||||
|
public interface OnUrlAppliedListener
|
||||||
|
{
|
||||||
|
void onUrlApplied(@NonNull String url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CustomMapServerDialog() {}
|
||||||
|
|
||||||
|
public static void show(@NonNull Context context,
|
||||||
|
@Nullable OnUrlAppliedListener listener)
|
||||||
|
{
|
||||||
|
View dialogView = LayoutInflater.from(context)
|
||||||
|
.inflate(R.layout.dialog_custom_map_server, null);
|
||||||
|
TextInputLayout til = dialogView.findViewById(R.id.til_custom_map_server);
|
||||||
|
TextInputEditText edit = dialogView.findViewById(R.id.edit_custom_map_server);
|
||||||
|
|
||||||
|
SharedPreferences prefs =
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
String current = prefs.getString(context.getString(R.string.pref_custom_map_download_url), "");
|
||||||
|
edit.setText(current);
|
||||||
|
|
||||||
|
MaterialAlertDialogBuilder builder =
|
||||||
|
new MaterialAlertDialogBuilder(context)
|
||||||
|
.setTitle(R.string.download_resources_custom_url_title)
|
||||||
|
.setMessage(R.string.download_resources_custom_url_message)
|
||||||
|
.setView(dialogView)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.save, null);
|
||||||
|
|
||||||
|
AlertDialog dialog = builder.create();
|
||||||
|
dialog.setOnShowListener(dlg -> {
|
||||||
|
Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||||
|
ok.setOnClickListener(v -> {
|
||||||
|
String url = edit.getText() != null ? edit.getText().toString().trim() : "";
|
||||||
|
|
||||||
|
if (!url.isEmpty()
|
||||||
|
&& !url.startsWith("http://")
|
||||||
|
&& !url.startsWith("https://"))
|
||||||
|
{
|
||||||
|
til.setError(context.getString(R.string.download_resources_custom_url_error_scheme));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
til.setError(null);
|
||||||
|
|
||||||
|
String normalizedUrl = Framework.normalizeServerUrl(url);
|
||||||
|
|
||||||
|
prefs.edit()
|
||||||
|
.putString(context.getString(R.string.pref_custom_map_download_url), normalizedUrl)
|
||||||
|
.apply();
|
||||||
|
|
||||||
|
// Apply to native
|
||||||
|
Framework.applyCustomMapDownloadUrl(context, normalizedUrl);
|
||||||
|
|
||||||
|
if (listener != null)
|
||||||
|
listener.onUrlApplied(normalizedUrl);
|
||||||
|
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -113,7 +113,7 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
|
|||||||
negativeButtonText = args.getString(ARG_NEGATIVE_BUTTON);
|
negativeButtonText = args.getString(ARG_NEGATIVE_BUTTON);
|
||||||
}
|
}
|
||||||
|
|
||||||
AlertDialog editTextDialog = new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
AlertDialog editTextDialog = new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setView(buildView())
|
.setView(buildView())
|
||||||
.setNegativeButton(negativeButtonText, null)
|
.setNegativeButton(negativeButtonText, null)
|
||||||
.setPositiveButton(positiveButtonText, null)
|
.setPositiveButton(positiveButtonText, null)
|
||||||
@@ -125,8 +125,7 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
|
|||||||
|
|
||||||
positiveButton.setOnClickListener(view -> {
|
positiveButton.setOnClickListener(view -> {
|
||||||
final String result = mEtInput.getText().toString();
|
final String result = mEtInput.getText().toString();
|
||||||
if (validateInput(requireActivity(), result))
|
if (validateInput(requireActivity(), result)) {
|
||||||
{
|
|
||||||
processInput(result);
|
processInput(result);
|
||||||
editTextDialog.dismiss();
|
editTextDialog.dismiss();
|
||||||
}
|
}
|
||||||
@@ -153,7 +152,7 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
|
|||||||
if (mInputValidator != null)
|
if (mInputValidator != null)
|
||||||
{
|
{
|
||||||
final String maybeError = mInputValidator.validate(activity, input);
|
final String maybeError = mInputValidator.validate(activity, input);
|
||||||
mEtInputLayout.getEditText().setError(maybeError);
|
mEtInputLayout.setError(maybeError);
|
||||||
mEtInputLayout.requestFocus();
|
mEtInputLayout.requestFocus();
|
||||||
return maybeError == null;
|
return maybeError == null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
{
|
{
|
||||||
if (RoutingController.get().isNavigating())
|
if (RoutingController.get().isNavigating())
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(adapter.mActivity, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(adapter.mActivity)
|
||||||
.setTitle(R.string.downloader_delete_map)
|
.setTitle(R.string.downloader_delete_map)
|
||||||
.setMessage(R.string.downloader_delete_map_while_routing_dialog)
|
.setMessage(R.string.downloader_delete_map_while_routing_dialog)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
@@ -133,7 +133,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new MaterialAlertDialogBuilder(adapter.mActivity, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(adapter.mActivity)
|
||||||
.setTitle(R.string.downloader_delete_map)
|
.setTitle(R.string.downloader_delete_map)
|
||||||
.setMessage(R.string.downloader_delete_map_dialog)
|
.setMessage(R.string.downloader_delete_map_dialog)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class MapManagerHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final AlertDialog dlg = new MaterialAlertDialogBuilder(activity, R.style.MwmTheme_AlertDialog)
|
final AlertDialog dlg = new MaterialAlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.country_status_download_failed)
|
.setTitle(R.string.country_status_download_failed)
|
||||||
.setMessage(getErrorCodeStrRes(errorData.errorCode))
|
.setMessage(getErrorCodeStrRes(errorData.errorCode))
|
||||||
.setNegativeButton(R.string.cancel,
|
.setNegativeButton(R.string.cancel,
|
||||||
@@ -72,7 +72,7 @@ public class MapManagerHelper
|
|||||||
|
|
||||||
private static void notifyNoSpaceInternal(Activity activity)
|
private static void notifyNoSpaceInternal(Activity activity)
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(activity, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.downloader_no_space_title)
|
.setTitle(R.string.downloader_no_space_title)
|
||||||
.setMessage(R.string.downloader_no_space_message)
|
.setMessage(R.string.downloader_no_space_message)
|
||||||
.setPositiveButton(android.R.string.ok, null)
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
@@ -123,7 +123,7 @@ public class MapManagerHelper
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
new MaterialAlertDialogBuilder(activity, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.download_over_mobile_header)
|
.setTitle(R.string.download_over_mobile_header)
|
||||||
.setMessage(R.string.download_over_mobile_message)
|
.setMessage(R.string.download_over_mobile_message)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.location.Location;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import app.organicmaps.MwmActivity;
|
import app.organicmaps.MwmActivity;
|
||||||
@@ -48,8 +49,7 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
@Override
|
@Override
|
||||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||||
{
|
{
|
||||||
if (mCurrentCountry == null)
|
if (mCurrentCountry == null) {
|
||||||
{
|
|
||||||
updateOfflineExplanationVisibility();
|
updateOfflineExplanationVisibility();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -109,13 +109,10 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
return enqueued || progress || applying;
|
return enqueued || progress || applying;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateOfflineExplanationVisibility()
|
private void updateOfflineExplanationVisibility() {
|
||||||
{
|
if (mOfflineExplanation == null) return;
|
||||||
if (mOfflineExplanation == null)
|
|
||||||
return;
|
|
||||||
// hide once threshold reached; safe to call repeatedly.
|
// hide once threshold reached; safe to call repeatedly.
|
||||||
app.organicmaps.util.UiUtils.showIf(MapManager.nativeGetDownloadedCount() < (DEFAULT_MAP_BASELINE + HIDE_THRESHOLD),
|
app.organicmaps.util.UiUtils.showIf(MapManager.nativeGetDownloadedCount() < (DEFAULT_MAP_BASELINE + HIDE_THRESHOLD), mOfflineExplanation);
|
||||||
mOfflineExplanation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateProgressState(boolean shouldAutoDownload)
|
private void updateProgressState(boolean shouldAutoDownload)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AutoCompleteTextView;
|
import android.widget.AutoCompleteTextView;
|
||||||
import android.widget.GridLayout;
|
import android.widget.GridLayout;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.IdRes;
|
import androidx.annotation.IdRes;
|
||||||
@@ -195,9 +196,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
{
|
{
|
||||||
final Context context = mInputBuildingLevels.getContext();
|
final Context context = mInputBuildingLevels.getContext();
|
||||||
final boolean isValid = Editor.nativeIsLevelValid(s.toString());
|
final boolean isValid = Editor.nativeIsLevelValid(s.toString());
|
||||||
UiUtils.setInputError(mInputBuildingLevels,
|
mInputBuildingLevels.setError(isValid ? null : context.getString(R.string.error_enter_correct_storey_number,
|
||||||
isValid ? null
|
|
||||||
: context.getString(R.string.error_enter_correct_storey_number,
|
|
||||||
Editor.nativeGetMaxEditableBuildingLevels()));
|
Editor.nativeGetMaxEditableBuildingLevels()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -397,7 +396,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
List<String> SOCKET_TYPES = Arrays.stream(getResources().getStringArray(R.array.charge_socket_types)).toList();
|
List<String> SOCKET_TYPES = Arrays.stream(getResources().getStringArray(R.array.charge_socket_types)).toList();
|
||||||
for (String socketType : SOCKET_TYPES)
|
for (String socketType : SOCKET_TYPES)
|
||||||
{
|
{
|
||||||
ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType, 0, 0);
|
ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType,0,0);
|
||||||
|
|
||||||
MaterialButton btn = (MaterialButton) inflater.inflate(R.layout.button_socket_type, typeBtns, false);
|
MaterialButton btn = (MaterialButton) inflater.inflate(R.layout.button_socket_type, typeBtns, false);
|
||||||
|
|
||||||
@@ -405,16 +404,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
|
|
||||||
// load SVG icon converted into VectorDrawable in res/drawable
|
// load SVG icon converted into VectorDrawable in res/drawable
|
||||||
@SuppressLint("DiscouragedApi")
|
@SuppressLint("DiscouragedApi")
|
||||||
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
|
int resIconId =
|
||||||
requireContext().getPackageName());
|
getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable", requireContext().getPackageName());
|
||||||
if (resIconId != 0)
|
if (resIconId != 0)
|
||||||
{
|
{
|
||||||
btn.setIcon(getResources().getDrawable(resIconId));
|
btn.setIcon(getResources().getDrawable(resIconId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DiscouragedApi")
|
@SuppressLint("DiscouragedApi")
|
||||||
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
|
int resTypeId =
|
||||||
requireContext().getPackageName());
|
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
|
||||||
if (resTypeId != 0)
|
if (resTypeId != 0)
|
||||||
{
|
{
|
||||||
btn.setText(getResources().getString(resTypeId));
|
btn.setText(getResources().getString(resTypeId));
|
||||||
@@ -462,16 +461,13 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
// Add a TextWatcher to validate on text change
|
// Add a TextWatcher to validate on text change
|
||||||
countView.addTextChangedListener(new TextWatcher() {
|
countView.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after)
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||||
{}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||||
{}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s)
|
public void afterTextChanged(Editable s) {
|
||||||
{
|
|
||||||
validatePositiveField(s.toString(), countInputLayout);
|
validatePositiveField(s.toString(), countInputLayout);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -486,25 +482,21 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
// Add a TextWatcher to validate on text change
|
// Add a TextWatcher to validate on text change
|
||||||
powerView.addTextChangedListener(new TextWatcher() {
|
powerView.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after)
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||||
{}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||||
{}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s)
|
public void afterTextChanged(Editable s) {
|
||||||
{
|
|
||||||
validatePositiveField(s.toString(), powerInputLayout);
|
validatePositiveField(s.toString(), powerInputLayout);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
return new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.editor_socket)
|
.setTitle(R.string.editor_socket)
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
.setPositiveButton(
|
.setPositiveButton(R.string.save,
|
||||||
R.string.save,
|
|
||||||
(dialog, which) -> {
|
(dialog, which) -> {
|
||||||
String socketType = "";
|
String socketType = "";
|
||||||
for (MaterialButton b : buttonList)
|
for (MaterialButton b : buttonList)
|
||||||
@@ -548,7 +540,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
|
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType, countValue, powerValue);
|
ChargeSocketDescriptor socket =
|
||||||
|
new ChargeSocketDescriptor(socketType, countValue, powerValue);
|
||||||
|
|
||||||
updateChargeSockets(socketIndex, socket);
|
updateChargeSockets(socketIndex, socket);
|
||||||
})
|
})
|
||||||
@@ -556,29 +549,21 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper method for validation logic
|
// Helper method for validation logic
|
||||||
private boolean validatePositiveField(String text, TextInputLayout layout)
|
private boolean validatePositiveField(String text, TextInputLayout layout) {
|
||||||
{
|
if (text.isEmpty()) {
|
||||||
if (text.isEmpty())
|
|
||||||
{
|
|
||||||
layout.setError(null); // No error if empty (assuming 0 is the default)
|
layout.setError(null); // No error if empty (assuming 0 is the default)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
double value = Double.parseDouble(text);
|
double value = Double.parseDouble(text);
|
||||||
if (value < 0)
|
if (value < 0) {
|
||||||
{
|
|
||||||
layout.setError(getString(R.string.error_value_must_be_positive));
|
layout.setError(getString(R.string.error_value_must_be_positive));
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
layout.setError(null);
|
layout.setError(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
} catch (NumberFormatException e) {
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
layout.setError(getString(R.string.error_invalid_number));
|
layout.setError(getString(R.string.error_invalid_number));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -598,8 +583,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
{
|
{
|
||||||
sockets[socketIndex] = socket;
|
sockets[socketIndex] = socket;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
List<ChargeSocketDescriptor> list = new ArrayList<>(Arrays.asList(sockets));
|
List<ChargeSocketDescriptor> list = new ArrayList<>(Arrays.asList(sockets));
|
||||||
list.add(socket);
|
list.add(socket);
|
||||||
sockets = list.toArray(new ChargeSocketDescriptor[0]);
|
sockets = list.toArray(new ChargeSocketDescriptor[0]);
|
||||||
@@ -617,8 +601,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
GridLayout socketsGrid = mChargeSockets.findViewById(R.id.socket_grid_editor);
|
GridLayout socketsGrid = mChargeSockets.findViewById(R.id.socket_grid_editor);
|
||||||
socketsGrid.removeAllViews();
|
socketsGrid.removeAllViews();
|
||||||
|
|
||||||
for (int i = 0; i < sockets.length; i++)
|
for (int i = 0; i < sockets.length; i++) {
|
||||||
{
|
|
||||||
final int currentIndex = i;
|
final int currentIndex = i;
|
||||||
ChargeSocketDescriptor socket = sockets[i];
|
ChargeSocketDescriptor socket = sockets[i];
|
||||||
|
|
||||||
@@ -629,30 +612,27 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
MaterialTextView power = itemView.findViewById(R.id.socket_power);
|
MaterialTextView power = itemView.findViewById(R.id.socket_power);
|
||||||
MaterialTextView count = itemView.findViewById(R.id.socket_count);
|
MaterialTextView count = itemView.findViewById(R.id.socket_count);
|
||||||
|
|
||||||
|
|
||||||
// load SVG icon converted into VectorDrawable in res/drawable
|
// load SVG icon converted into VectorDrawable in res/drawable
|
||||||
@SuppressLint("DiscouragedApi")
|
@SuppressLint("DiscouragedApi")
|
||||||
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
|
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
|
||||||
requireContext().getPackageName());
|
requireContext().getPackageName());
|
||||||
if (resIconId != 0)
|
if (resIconId != 0) {
|
||||||
{
|
|
||||||
icon.setImageResource(resIconId);
|
icon.setImageResource(resIconId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DiscouragedApi")
|
@SuppressLint("DiscouragedApi")
|
||||||
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
|
int resTypeId =
|
||||||
requireContext().getPackageName());
|
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
|
||||||
if (resTypeId != 0)
|
if (resTypeId != 0) {
|
||||||
{
|
|
||||||
type.setText(resTypeId);
|
type.setText(resTypeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket.power() != 0)
|
if (socket.power() != 0) {
|
||||||
{
|
|
||||||
DecimalFormat df = new DecimalFormat("#.##");
|
DecimalFormat df = new DecimalFormat("#.##");
|
||||||
power.setText(getString(R.string.kw_label, df.format(socket.power())));
|
power.setText(getString(R.string.kw_label, df.format(socket.power())));
|
||||||
}
|
}
|
||||||
else if (socket.ignorePower())
|
else if (socket.ignorePower()) {
|
||||||
{
|
|
||||||
power.setVisibility(INVISIBLE);
|
power.setVisibility(INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,8 +641,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
count.setText(getString(R.string.count_label, socket.count()));
|
count.setText(getString(R.string.count_label, socket.count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
itemView.setOnClickListener(
|
itemView.setOnClickListener(v -> buildChargeSocketDialog(currentIndex, socket.type(), socket.count(), socket.power()).show());
|
||||||
v -> buildChargeSocketDialog(currentIndex, socket.type(), socket.count(), socket.power()).show());
|
|
||||||
socketsGrid.addView(itemView);
|
socketsGrid.addView(itemView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,8 +787,9 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
View lineContactBlock =
|
View lineContactBlock =
|
||||||
initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, R.drawable.ic_line_white,
|
initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, R.drawable.ic_line_white,
|
||||||
R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI);
|
R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI);
|
||||||
View blueskyContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky,
|
View blueskyContactBlock =
|
||||||
R.drawable.ic_bluesky, R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
|
initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky, R.drawable.ic_bluesky,
|
||||||
|
R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
|
||||||
View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator,
|
View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator,
|
||||||
R.drawable.ic_operator, R.string.editor_operator, 0);
|
R.drawable.ic_operator, R.string.editor_operator, 0);
|
||||||
|
|
||||||
@@ -966,7 +946,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
|
|
||||||
mDisused.setVisibility(Editor.nativeCanMarkPlaceAsDisused() ? View.VISIBLE : View.GONE);
|
mDisused.setVisibility(Editor.nativeCanMarkPlaceAsDisused() ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
if (Editor.nativeIsMapObjectUploaded())
|
if (Editor.nativeAreSomeFeatureChangesUploaded())
|
||||||
{
|
{
|
||||||
mReset.setText(R.string.editor_place_doesnt_exist);
|
mReset.setText(R.string.editor_place_doesnt_exist);
|
||||||
return;
|
return;
|
||||||
@@ -984,7 +964,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
|
|
||||||
private void reset()
|
private void reset()
|
||||||
{
|
{
|
||||||
if (Editor.nativeIsMapObjectUploaded())
|
if (Editor.nativeAreSomeFeatureChangesUploaded())
|
||||||
{
|
{
|
||||||
placeDoesntExist();
|
placeDoesntExist();
|
||||||
return;
|
return;
|
||||||
@@ -1017,7 +997,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
message = R.string.editor_reset_edits_message;
|
message = R.string.editor_reset_edits_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(message)
|
.setTitle(message)
|
||||||
.setPositiveButton(title,
|
.setPositiveButton(title,
|
||||||
(dialog, which) -> {
|
(dialog, which) -> {
|
||||||
@@ -1040,11 +1020,10 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
|
|
||||||
private void placeDisused()
|
private void placeDisused()
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.editor_mark_business_vacant_title)
|
.setTitle(R.string.editor_mark_business_vacant_title)
|
||||||
.setMessage(R.string.editor_mark_business_vacant_description)
|
.setMessage(R.string.editor_mark_business_vacant_description)
|
||||||
.setPositiveButton(R.string.editor_submit,
|
.setPositiveButton(R.string.editor_submit, (dlg, which) -> {
|
||||||
(dlg, which) -> {
|
|
||||||
Editor.nativeMarkPlaceAsDisused();
|
Editor.nativeMarkPlaceAsDisused();
|
||||||
mParent.processEditedFeatures();
|
mParent.processEditedFeatures();
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ public class EditorHostFragment
|
|||||||
|
|
||||||
private void processNoFeatures()
|
private void processNoFeatures()
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.downloader_no_space_title)
|
.setTitle(R.string.downloader_no_space_title)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show();
|
.show();
|
||||||
@@ -386,7 +386,7 @@ public class EditorHostFragment
|
|||||||
|
|
||||||
private void showNoobDialog()
|
private void showNoobDialog()
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.editor_share_to_all_dialog_title)
|
.setTitle(R.string.editor_share_to_all_dialog_title)
|
||||||
.setMessage(getString(R.string.editor_share_to_all_dialog_message_1) + " "
|
.setMessage(getString(R.string.editor_share_to_all_dialog_message_1) + " "
|
||||||
+ getString(R.string.editor_share_to_all_dialog_message_2))
|
+ getString(R.string.editor_share_to_all_dialog_message_2))
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import app.organicmaps.R;
|
|||||||
import app.organicmaps.sdk.editor.data.FeatureCategory;
|
import app.organicmaps.sdk.editor.data.FeatureCategory;
|
||||||
import app.organicmaps.sdk.util.StringUtils;
|
import app.organicmaps.sdk.util.StringUtils;
|
||||||
import app.organicmaps.util.UiUtils;
|
import app.organicmaps.util.UiUtils;
|
||||||
|
|
||||||
import com.google.android.material.button.MaterialButton;
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.textfield.TextInputEditText;
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
@@ -68,7 +69,8 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
|
|||||||
}
|
}
|
||||||
case TYPE_FOOTER ->
|
case TYPE_FOOTER ->
|
||||||
{
|
{
|
||||||
return new FooterViewHolder(inflater.inflate(R.layout.item_feature_category_footer, parent, false), mFragment);
|
return new FooterViewHolder(inflater.inflate(R.layout.item_feature_category_footer, parent, false),
|
||||||
|
mFragment);
|
||||||
}
|
}
|
||||||
default -> throw new IllegalArgumentException("Unsupported viewType: " + viewType);
|
default -> throw new IllegalArgumentException("Unsupported viewType: " + viewType);
|
||||||
}
|
}
|
||||||
@@ -132,21 +134,26 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
|
|||||||
mSendNoteButton = itemView.findViewById(R.id.send_note_button);
|
mSendNoteButton = itemView.findViewById(R.id.send_note_button);
|
||||||
mSendNoteButton.setOnClickListener(v -> listener.onSendNoteClicked());
|
mSendNoteButton.setOnClickListener(v -> listener.onSendNoteClicked());
|
||||||
final ColorStateList bgButtonColor = new ColorStateList(
|
final ColorStateList bgButtonColor = new ColorStateList(
|
||||||
new int[][] {
|
new int[][]{
|
||||||
new int[] {android.R.attr.state_enabled}, // enabled
|
new int[]{android.R.attr.state_enabled}, // enabled
|
||||||
new int[] {-android.R.attr.state_enabled} // disabled
|
new int[]{-android.R.attr.state_enabled} // disabled
|
||||||
},
|
},
|
||||||
new int[] {ContextCompat.getColor(mSendNoteButton.getContext(), R.color.base_accent),
|
new int[]{
|
||||||
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_disabled)});
|
ContextCompat.getColor(
|
||||||
|
mSendNoteButton.getContext(), R.color.base_accent),
|
||||||
|
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_disabled)
|
||||||
|
});
|
||||||
final ColorStateList textButtonColor = new ColorStateList(
|
final ColorStateList textButtonColor = new ColorStateList(
|
||||||
new int[][] {
|
new int[][]{
|
||||||
new int[] {android.R.attr.state_enabled}, // enabled
|
new int[]{android.R.attr.state_enabled}, // enabled
|
||||||
new int[] {-android.R.attr.state_enabled} // disabled
|
new int[]{-android.R.attr.state_enabled} // disabled
|
||||||
},
|
},
|
||||||
new int[] {ContextCompat.getColor(mSendNoteButton.getContext(),
|
new int[]{
|
||||||
UiUtils.getStyledResourceId(mSendNoteButton.getContext(),
|
ContextCompat.getColor(
|
||||||
android.R.attr.textColorPrimaryInverse)),
|
mSendNoteButton.getContext(),
|
||||||
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_text_disabled)});
|
UiUtils.getStyledResourceId(mSendNoteButton.getContext(), android.R.attr.textColorPrimaryInverse)),
|
||||||
|
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_text_disabled)
|
||||||
|
});
|
||||||
mSendNoteButton.setBackgroundTintList(bgButtonColor);
|
mSendNoteButton.setBackgroundTintList(bgButtonColor);
|
||||||
mSendNoteButton.setTextColor(textButtonColor);
|
mSendNoteButton.setTextColor(textButtonColor);
|
||||||
mNoteEditText.addTextChangedListener(new StringUtils.SimpleTextWatcher() {
|
mNoteEditText.addTextChangedListener(new StringUtils.SimpleTextWatcher() {
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ public class FeatureCategoryFragment
|
|||||||
// Duplicate of showNoobDialog()
|
// Duplicate of showNoobDialog()
|
||||||
private void showNoteConfirmationDialog(double lat, double lon, String noteText)
|
private void showNoteConfirmationDialog(double lat, double lon, String noteText)
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.editor_share_to_all_dialog_title)
|
.setTitle(R.string.editor_share_to_all_dialog_title)
|
||||||
.setMessage(getString(R.string.editor_share_to_all_dialog_message_1) + " "
|
.setMessage(getString(R.string.editor_share_to_all_dialog_message_1) + " "
|
||||||
+ getString(R.string.editor_share_to_all_dialog_message_2))
|
+ getString(R.string.editor_share_to_all_dialog_message_2))
|
||||||
|
|||||||
@@ -2,16 +2,19 @@ package app.organicmaps.editor;
|
|||||||
|
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
import com.google.android.material.timepicker.MaterialTimePicker;
|
||||||
|
import com.google.android.material.timepicker.TimeFormat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.editor.data.HoursMinutes;
|
import app.organicmaps.sdk.editor.data.HoursMinutes;
|
||||||
import app.organicmaps.sdk.util.DateUtils;
|
import app.organicmaps.sdk.util.DateUtils;
|
||||||
import com.google.android.material.timepicker.MaterialTimePicker;
|
|
||||||
import com.google.android.material.timepicker.TimeFormat;
|
|
||||||
|
|
||||||
public class FromToTimePicker
|
public class FromToTimePicker
|
||||||
{
|
{
|
||||||
@@ -29,11 +32,18 @@ public class FromToTimePicker
|
|||||||
private boolean mIsFromTimePicked;
|
private boolean mIsFromTimePicked;
|
||||||
private int mInputMode;
|
private int mInputMode;
|
||||||
|
|
||||||
public static void pickTime(@NonNull Fragment fragment, @NonNull FromToTimePicker.OnPickListener listener,
|
public static void pickTime(@NonNull Fragment fragment,
|
||||||
@NonNull HoursMinutes fromTime, @NonNull HoursMinutes toTime, int id,
|
@NonNull FromToTimePicker.OnPickListener listener,
|
||||||
|
@NonNull HoursMinutes fromTime,
|
||||||
|
@NonNull HoursMinutes toTime,
|
||||||
|
int id,
|
||||||
boolean startWithToTime)
|
boolean startWithToTime)
|
||||||
{
|
{
|
||||||
FromToTimePicker timePicker = new FromToTimePicker(fragment, listener, fromTime, toTime, id);
|
FromToTimePicker timePicker = new FromToTimePicker(fragment,
|
||||||
|
listener,
|
||||||
|
fromTime,
|
||||||
|
toTime,
|
||||||
|
id);
|
||||||
|
|
||||||
if (startWithToTime)
|
if (startWithToTime)
|
||||||
timePicker.showToTimePicker();
|
timePicker.showToTimePicker();
|
||||||
@@ -41,8 +51,11 @@ public class FromToTimePicker
|
|||||||
timePicker.showFromTimePicker();
|
timePicker.showFromTimePicker();
|
||||||
}
|
}
|
||||||
|
|
||||||
private FromToTimePicker(@NonNull Fragment fragment, @NonNull FromToTimePicker.OnPickListener listener,
|
private FromToTimePicker(@NonNull Fragment fragment,
|
||||||
@NonNull HoursMinutes fromTime, @NonNull HoursMinutes toTime, int id)
|
@NonNull FromToTimePicker.OnPickListener listener,
|
||||||
|
@NonNull HoursMinutes fromTime,
|
||||||
|
@NonNull HoursMinutes toTime,
|
||||||
|
int id)
|
||||||
{
|
{
|
||||||
mActivity = fragment.requireActivity();
|
mActivity = fragment.requireActivity();
|
||||||
mFragmentManager = fragment.getChildFragmentManager();
|
mFragmentManager = fragment.getChildFragmentManager();
|
||||||
@@ -87,12 +100,15 @@ public class FromToTimePicker
|
|||||||
|
|
||||||
private MaterialTimePicker buildFromTimePicker()
|
private MaterialTimePicker buildFromTimePicker()
|
||||||
{
|
{
|
||||||
MaterialTimePicker timePicker = buildTimePicker(mFromTime, mResources.getString(R.string.editor_time_from),
|
MaterialTimePicker timePicker = buildTimePicker(mFromTime,
|
||||||
mResources.getString(R.string.next_button), null);
|
mResources.getString(R.string.editor_time_from),
|
||||||
|
mResources.getString(R.string.next_button),
|
||||||
|
null);
|
||||||
|
|
||||||
timePicker.addOnNegativeButtonClickListener(view -> finishTimePicking(false));
|
timePicker.addOnNegativeButtonClickListener(view -> finishTimePicking(false));
|
||||||
|
|
||||||
timePicker.addOnPositiveButtonClickListener(view -> {
|
timePicker.addOnPositiveButtonClickListener(view ->
|
||||||
|
{
|
||||||
mIsFromTimePicked = true;
|
mIsFromTimePicked = true;
|
||||||
saveState(timePicker, true);
|
saveState(timePicker, true);
|
||||||
mFromTimePicker = null;
|
mFromTimePicker = null;
|
||||||
@@ -106,10 +122,13 @@ public class FromToTimePicker
|
|||||||
|
|
||||||
private MaterialTimePicker buildToTimePicker()
|
private MaterialTimePicker buildToTimePicker()
|
||||||
{
|
{
|
||||||
MaterialTimePicker timePicker = buildTimePicker(mToTime, mResources.getString(R.string.editor_time_to), null,
|
MaterialTimePicker timePicker = buildTimePicker(mToTime,
|
||||||
|
mResources.getString(R.string.editor_time_to),
|
||||||
|
null,
|
||||||
mResources.getString(R.string.back));
|
mResources.getString(R.string.back));
|
||||||
|
|
||||||
timePicker.addOnNegativeButtonClickListener(view -> {
|
timePicker.addOnNegativeButtonClickListener(view ->
|
||||||
|
{
|
||||||
saveState(timePicker, false);
|
saveState(timePicker, false);
|
||||||
mToTimePicker = null;
|
mToTimePicker = null;
|
||||||
if (mIsFromTimePicked)
|
if (mIsFromTimePicked)
|
||||||
@@ -118,7 +137,8 @@ public class FromToTimePicker
|
|||||||
finishTimePicking(false);
|
finishTimePicking(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
timePicker.addOnPositiveButtonClickListener(view -> {
|
timePicker.addOnPositiveButtonClickListener(view ->
|
||||||
|
{
|
||||||
saveState(timePicker, false);
|
saveState(timePicker, false);
|
||||||
finishTimePicking(true);
|
finishTimePicking(true);
|
||||||
});
|
});
|
||||||
@@ -129,12 +149,12 @@ public class FromToTimePicker
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private MaterialTimePicker buildTimePicker(@NonNull HoursMinutes time, @NonNull String title,
|
private MaterialTimePicker buildTimePicker(@NonNull HoursMinutes time,
|
||||||
|
@NonNull String title,
|
||||||
@Nullable String positiveButtonTextOverride,
|
@Nullable String positiveButtonTextOverride,
|
||||||
@Nullable String negativeButtonTextOverride)
|
@Nullable String negativeButtonTextOverride)
|
||||||
{
|
{
|
||||||
MaterialTimePicker.Builder builder =
|
MaterialTimePicker.Builder builder = new MaterialTimePicker.Builder()
|
||||||
new MaterialTimePicker.Builder()
|
|
||||||
.setTitleText(title)
|
.setTitleText(title)
|
||||||
.setTimeFormat(mIs24HourFormat ? TimeFormat.CLOCK_24H : TimeFormat.CLOCK_12H)
|
.setTimeFormat(mIs24HourFormat ? TimeFormat.CLOCK_24H : TimeFormat.CLOCK_12H)
|
||||||
.setInputMode(mInputMode)
|
.setInputMode(mInputMode)
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment
|
|||||||
|
|
||||||
private void onAuthFail()
|
private void onAuthFail()
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.editor_login_error_dialog)
|
.setTitle(R.string.editor_login_error_dialog)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show();
|
.show();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import androidx.annotation.IdRes;
|
import androidx.annotation.IdRes;
|
||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -121,14 +122,20 @@ class SimpleTimetableAdapter extends RecyclerView.Adapter<SimpleTimetableAdapter
|
|||||||
notifyItemChanged(getItemCount() - 1);
|
notifyItemChanged(getItemCount() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pickTime(int position, @IntRange(from = ID_OPENING_TIME, to = ID_CLOSED_SPAN) int id,
|
private void pickTime(int position,
|
||||||
|
@IntRange(from = ID_OPENING_TIME, to = ID_CLOSED_SPAN) int id,
|
||||||
boolean startWithToTime)
|
boolean startWithToTime)
|
||||||
{
|
{
|
||||||
final Timetable data = mItems.get(position);
|
final Timetable data = mItems.get(position);
|
||||||
mPickingPosition = position;
|
mPickingPosition = position;
|
||||||
|
|
||||||
FromToTimePicker.pickTime(mFragment, this, data.workingTimespan.start, data.workingTimespan.end, id,
|
FromToTimePicker.pickTime(mFragment,
|
||||||
|
this,
|
||||||
|
data.workingTimespan.start,
|
||||||
|
data.workingTimespan.end,
|
||||||
|
id,
|
||||||
startWithToTime);
|
startWithToTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -377,21 +384,26 @@ class SimpleTimetableAdapter extends RecyclerView.Adapter<SimpleTimetableAdapter
|
|||||||
final String text = mFragment.getString(R.string.editor_time_add);
|
final String text = mFragment.getString(R.string.editor_time_add);
|
||||||
mAdd.setEnabled(enable);
|
mAdd.setEnabled(enable);
|
||||||
final ColorStateList bgButtonColor = new ColorStateList(
|
final ColorStateList bgButtonColor = new ColorStateList(
|
||||||
new int[][] {
|
new int[][]{
|
||||||
new int[] {android.R.attr.state_enabled}, // enabled
|
new int[]{android.R.attr.state_enabled}, // enabled
|
||||||
new int[] {-android.R.attr.state_enabled} // disabled
|
new int[]{-android.R.attr.state_enabled} // disabled
|
||||||
},
|
},
|
||||||
new int[] {ContextCompat.getColor(mAdd.getContext(), R.color.base_accent),
|
new int[]{
|
||||||
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_disabled)});
|
ContextCompat.getColor(
|
||||||
|
mAdd.getContext(), R.color.base_accent),
|
||||||
|
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_disabled)
|
||||||
|
});
|
||||||
final ColorStateList textButtonColor = new ColorStateList(
|
final ColorStateList textButtonColor = new ColorStateList(
|
||||||
new int[][] {
|
new int[][]{
|
||||||
new int[] {android.R.attr.state_enabled}, // enabled
|
new int[]{android.R.attr.state_enabled}, // enabled
|
||||||
new int[] {-android.R.attr.state_enabled} // disabled
|
new int[]{-android.R.attr.state_enabled} // disabled
|
||||||
},
|
},
|
||||||
new int[] {
|
new int[]{
|
||||||
ContextCompat.getColor(mAdd.getContext(), UiUtils.getStyledResourceId(
|
ContextCompat.getColor(
|
||||||
mAdd.getContext(), android.R.attr.textColorPrimaryInverse)),
|
mAdd.getContext(),
|
||||||
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_text_disabled)});
|
UiUtils.getStyledResourceId(mAdd.getContext(), android.R.attr.textColorPrimaryInverse)),
|
||||||
|
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_text_disabled)
|
||||||
|
});
|
||||||
mAdd.setBackgroundTintList(bgButtonColor);
|
mAdd.setBackgroundTintList(bgButtonColor);
|
||||||
mAdd.setTextColor(textButtonColor);
|
mAdd.setTextColor(textButtonColor);
|
||||||
mAdd.setText(enable ? text + " (" + TimeFormatUtils.formatWeekdays(mComplementItem) + ")" : text);
|
mAdd.setText(enable ? text + " (" + TimeFormatUtils.formatWeekdays(mComplementItem) + ")" : text);
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import androidx.annotation.Nullable;
|
|||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmRecyclerFragment;
|
import app.organicmaps.base.BaseMwmRecyclerFragment;
|
||||||
|
|
||||||
public class SimpleTimetableFragment
|
public class SimpleTimetableFragment extends BaseMwmRecyclerFragment<SimpleTimetableAdapter>
|
||||||
extends BaseMwmRecyclerFragment<SimpleTimetableAdapter> implements TimetableProvider
|
implements TimetableProvider
|
||||||
{
|
{
|
||||||
private SimpleTimetableAdapter mAdapter;
|
private SimpleTimetableAdapter mAdapter;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class FaqFragment extends BaseMwmFragment
|
|||||||
FloatingActionButton feedbackFab = root.findViewById(R.id.feedback_fab);
|
FloatingActionButton feedbackFab = root.findViewById(R.id.feedback_fab);
|
||||||
feedbackFab.setOnClickListener(
|
feedbackFab.setOnClickListener(
|
||||||
v
|
v
|
||||||
-> new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
-> new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.feedback)
|
.setTitle(R.string.feedback)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.setItems(new CharSequence[] {getString(R.string.feedback_general), getString(R.string.report_a_bug)},
|
.setItems(new CharSequence[] {getString(R.string.feedback_general), getString(R.string.report_a_bug)},
|
||||||
|
|||||||
@@ -35,25 +35,20 @@ public class LayerBottomSheetItem
|
|||||||
@DrawableRes
|
@DrawableRes
|
||||||
int drawableResId = 0;
|
int drawableResId = 0;
|
||||||
@StringRes
|
@StringRes
|
||||||
int buttonTextResource = switch (mode)
|
int buttonTextResource = switch (mode) {
|
||||||
{
|
case OUTDOORS -> {
|
||||||
case OUTDOORS ->
|
|
||||||
{
|
|
||||||
drawableResId = R.drawable.ic_layers_outdoors;
|
drawableResId = R.drawable.ic_layers_outdoors;
|
||||||
yield R.string.button_layer_outdoor;
|
yield R.string.button_layer_outdoor;
|
||||||
}
|
}
|
||||||
case SUBWAY ->
|
case SUBWAY -> {
|
||||||
{
|
|
||||||
drawableResId = R.drawable.ic_layers_subway;
|
drawableResId = R.drawable.ic_layers_subway;
|
||||||
yield R.string.subway;
|
yield R.string.subway;
|
||||||
}
|
}
|
||||||
case ISOLINES ->
|
case ISOLINES -> {
|
||||||
{
|
|
||||||
drawableResId = R.drawable.ic_layers_isoline;
|
drawableResId = R.drawable.ic_layers_isoline;
|
||||||
yield R.string.button_layer_isolines;
|
yield R.string.button_layer_isolines;
|
||||||
}
|
}
|
||||||
case TRAFFIC ->
|
case TRAFFIC -> {
|
||||||
{
|
|
||||||
drawableResId = R.drawable.ic_layers_traffic;
|
drawableResId = R.drawable.ic_layers_traffic;
|
||||||
yield R.string.button_layer_traffic;
|
yield R.string.button_layer_traffic;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import android.widget.ImageView;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.adapter.OnItemClickListener;
|
import app.organicmaps.adapter.OnItemClickListener;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
|
|
||||||
class LayerHolder extends RecyclerView.ViewHolder
|
class LayerHolder extends RecyclerView.ViewHolder
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class TrafficButtonController implements TrafficManager.TrafficCallback
|
|||||||
if (mDialog != null && mDialog.isShowing())
|
if (mDialog != null && mDialog.isShowing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mDialog = new MaterialAlertDialogBuilder(mActivity, R.style.MwmTheme_AlertDialog)
|
mDialog = new MaterialAlertDialogBuilder(mActivity)
|
||||||
.setMessage(R.string.common_check_internet_connection_dialog)
|
.setMessage(R.string.common_check_internet_connection_dialog)
|
||||||
.setPositiveButton(R.string.ok, (dialog, which) -> TrafficManager.INSTANCE.setEnabled(false))
|
.setPositiveButton(R.string.ok, (dialog, which) -> TrafficManager.INSTANCE.setEnabled(false))
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ abstract class BaseRoutingErrorDialogFragment extends BaseMwmDialogFragment
|
|||||||
public Dialog onCreateDialog(Bundle savedInstanceState)
|
public Dialog onCreateDialog(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
parseArguments();
|
parseArguments();
|
||||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setNegativeButton(android.R.string.cancel, null);
|
.setNegativeButton(android.R.string.cancel, null);
|
||||||
beforeDialogCreated(builder);
|
beforeDialogCreated(builder);
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav
|
|||||||
mSpeedLimit = topFrame.findViewById(R.id.nav_speed_limit);
|
mSpeedLimit = topFrame.findViewById(R.id.nav_speed_limit);
|
||||||
mCurrentSpeed = topFrame.findViewById(R.id.nav_current_speed);
|
mCurrentSpeed = topFrame.findViewById(R.id.nav_current_speed);
|
||||||
|
|
||||||
|
View mTopbar = topFrame.findViewById(R.id.statutbar);
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(mTopbar,(v, windowInsets) -> {
|
||||||
|
UiUtils.setViewNavigationTopInsetsMargin(v, windowInsets);
|
||||||
|
return windowInsets;
|
||||||
|
});
|
||||||
// Show a blank view below the navbar to hide the menu content
|
// Show a blank view below the navbar to hide the menu content
|
||||||
final View navigationBarBackground = mFrame.findViewById(R.id.nav_bottom_sheet_nav_bar);
|
final View navigationBarBackground = mFrame.findViewById(R.id.nav_bottom_sheet_nav_bar);
|
||||||
final View nextTurnContainer = mFrame.findViewById(R.id.nav_next_turn_container);
|
final View nextTurnContainer = mFrame.findViewById(R.id.nav_next_turn_container);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import app.organicmaps.util.UiUtils;
|
|||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.widget.recycler.DotDividerItemDecoration;
|
import app.organicmaps.widget.recycler.DotDividerItemDecoration;
|
||||||
import app.organicmaps.widget.recycler.MultilineLayoutManager;
|
import app.organicmaps.widget.recycler.MultilineLayoutManager;
|
||||||
|
|
||||||
import com.google.android.material.button.MaterialButton;
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.imageview.ShapeableImageView;
|
import com.google.android.material.imageview.ShapeableImageView;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
@@ -122,9 +123,9 @@ final class RoutingBottomMenuController implements View.OnClickListener
|
|||||||
@NonNull View timeElevationLine, @NonNull View transitFrame,
|
@NonNull View timeElevationLine, @NonNull View transitFrame,
|
||||||
@NonNull MaterialTextView error, @NonNull MaterialButton start,
|
@NonNull MaterialTextView error, @NonNull MaterialButton start,
|
||||||
@NonNull ShapeableImageView altitudeChart, @NonNull MaterialTextView time,
|
@NonNull ShapeableImageView altitudeChart, @NonNull MaterialTextView time,
|
||||||
@NonNull MaterialTextView altitudeDifference,
|
@NonNull MaterialTextView altitudeDifference, @NonNull MaterialTextView timeVehicle,
|
||||||
@NonNull MaterialTextView timeVehicle, @Nullable MaterialTextView arrival,
|
@Nullable MaterialTextView arrival, @NonNull View actionFrame,
|
||||||
@NonNull View actionFrame, @Nullable RoutingBottomMenuListener listener)
|
@Nullable RoutingBottomMenuListener listener)
|
||||||
{
|
{
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mAltitudeChartFrame = altitudeChartFrame;
|
mAltitudeChartFrame = altitudeChartFrame;
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ import androidx.annotation.IdRes;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.Framework;
|
import app.organicmaps.sdk.Framework;
|
||||||
@@ -26,7 +29,6 @@ import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
|||||||
import app.organicmaps.widget.RoutingToolbarButton;
|
import app.organicmaps.widget.RoutingToolbarButton;
|
||||||
import app.organicmaps.widget.ToolbarController;
|
import app.organicmaps.widget.ToolbarController;
|
||||||
import app.organicmaps.widget.WheelProgressView;
|
import app.organicmaps.widget.WheelProgressView;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
|
|
||||||
public class RoutingPlanController extends ToolbarController
|
public class RoutingPlanController extends ToolbarController
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.search.DisplayedCategories;
|
import app.organicmaps.sdk.search.DisplayedCategories;
|
||||||
import app.organicmaps.sdk.util.Language;
|
import app.organicmaps.sdk.util.Language;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.search.SearchResult;
|
import app.organicmaps.sdk.search.SearchResult;
|
||||||
import app.organicmaps.util.Graphics;
|
import app.organicmaps.util.Graphics;
|
||||||
import app.organicmaps.util.ThemeUtils;
|
import app.organicmaps.util.ThemeUtils;
|
||||||
import app.organicmaps.util.UiUtils;
|
import app.organicmaps.util.UiUtils;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
|
|
||||||
class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHolder>
|
class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHolder>
|
||||||
{
|
{
|
||||||
@@ -150,8 +152,7 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
|
|||||||
{
|
{
|
||||||
final Resources resources = mSearchFragment.getResources();
|
final Resources resources = mSearchFragment.getResources();
|
||||||
|
|
||||||
if (result.description.openNow != SearchResult.OPEN_NOW_YES
|
if (result.description.openNow != SearchResult.OPEN_NOW_YES && result.description.openNow != SearchResult.OPEN_NOW_NO)
|
||||||
&& result.description.openNow != SearchResult.OPEN_NOW_NO)
|
|
||||||
{
|
{
|
||||||
// Hide if unknown opening hours state
|
// Hide if unknown opening hours state
|
||||||
UiUtils.hide(mOpen);
|
UiUtils.hide(mOpen);
|
||||||
@@ -168,18 +169,15 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
|
|||||||
{
|
{
|
||||||
final String minsToChangeStr = resources.getQuantityString(
|
final String minsToChangeStr = resources.getQuantityString(
|
||||||
R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1));
|
R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1));
|
||||||
final String nextChangeFormatted =
|
final String nextChangeFormatted = resources.getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr);
|
||||||
resources.getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr);
|
|
||||||
|
|
||||||
UiUtils.setTextAndShow(mOpen, nextChangeFormatted);
|
UiUtils.setTextAndShow(mOpen, nextChangeFormatted);
|
||||||
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_yellow));
|
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_yellow));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UiUtils.setTextAndShow(
|
UiUtils.setTextAndShow(mOpen, isOpen ? resources.getString(R.string.editor_time_open) : resources.getString(R.string.closed));
|
||||||
mOpen, isOpen ? resources.getString(R.string.editor_time_open) : resources.getString(R.string.closed));
|
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), isOpen ? R.color.base_green : R.color.base_red));
|
||||||
mOpen.setTextColor(
|
|
||||||
ContextCompat.getColor(mSearchFragment.getContext(), isOpen ? R.color.base_green : R.color.base_red));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -273,8 +273,7 @@ public class SearchFragment extends BaseMwmFragment implements SearchListener, C
|
|||||||
RecyclerView mResults = mResultsFrame.findViewById(R.id.recycler);
|
RecyclerView mResults = mResultsFrame.findViewById(R.id.recycler);
|
||||||
setRecyclerScrollListener(mResults);
|
setRecyclerScrollListener(mResults);
|
||||||
mResultsPlaceholder = mResultsFrame.findViewById(R.id.placeholder);
|
mResultsPlaceholder = mResultsFrame.findViewById(R.id.placeholder);
|
||||||
mResultsPlaceholder.setContent(R.string.search_not_found, R.string.search_not_found_query,
|
mResultsPlaceholder.setContent(R.string.search_not_found, R.string.search_not_found_query, R.drawable.ic_search_fail);
|
||||||
R.drawable.ic_search_fail);
|
|
||||||
mSearchAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
|
mSearchAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,13 +5,15 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.routing.RoutingController;
|
import app.organicmaps.sdk.routing.RoutingController;
|
||||||
import app.organicmaps.sdk.search.SearchRecents;
|
import app.organicmaps.sdk.search.SearchRecents;
|
||||||
import app.organicmaps.util.Graphics;
|
import app.organicmaps.util.Graphics;
|
||||||
import app.organicmaps.widget.SearchToolbarController;
|
import app.organicmaps.widget.SearchToolbarController;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
|
|
||||||
class SearchHistoryAdapter extends RecyclerView.Adapter<SearchHistoryAdapter.ViewHolder>
|
class SearchHistoryAdapter extends RecyclerView.Adapter<SearchHistoryAdapter.ViewHolder>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,12 +6,10 @@ import android.view.View;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.XmlRes;
|
import androidx.annotation.XmlRes;
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceFragmentCompat;
|
import androidx.preference.PreferenceFragmentCompat;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import app.organicmaps.R;
|
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.util.WindowInsetUtils.ScrollableContentInsetsListener;
|
import app.organicmaps.util.WindowInsetUtils.ScrollableContentInsetsListener;
|
||||||
|
|
||||||
@@ -44,7 +42,6 @@ abstract class BaseXmlSettingsFragment extends PreferenceFragmentCompat
|
|||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
view.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.bg_cards));
|
|
||||||
RecyclerView recyclerView = getListView();
|
RecyclerView recyclerView = getListView();
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(recyclerView, new ScrollableContentInsetsListener(recyclerView));
|
ViewCompat.setOnApplyWindowInsetsListener(recyclerView, new ScrollableContentInsetsListener(recyclerView));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.android.material.materialswitch.MaterialSwitch;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmToolbarFragment;
|
import app.organicmaps.base.BaseMwmToolbarFragment;
|
||||||
import app.organicmaps.sdk.routing.RoutingController;
|
import app.organicmaps.sdk.routing.RoutingController;
|
||||||
import app.organicmaps.sdk.routing.RoutingOptions;
|
import app.organicmaps.sdk.routing.RoutingOptions;
|
||||||
import app.organicmaps.sdk.settings.RoadType;
|
import app.organicmaps.sdk.settings.RoadType;
|
||||||
import com.google.android.material.materialswitch.MaterialSwitch;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|||||||
@@ -4,16 +4,23 @@ import static app.organicmaps.leftbutton.LeftButtonsHolder.DISABLE_BUTTON_CODE;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceCategory;
|
import androidx.preference.PreferenceCategory;
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.preference.TwoStatePreference;
|
import androidx.preference.TwoStatePreference;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
|
import app.organicmaps.dialog.CustomMapServerDialog;
|
||||||
import app.organicmaps.downloader.OnmapDownloader;
|
import app.organicmaps.downloader.OnmapDownloader;
|
||||||
import app.organicmaps.editor.LanguagesFragment;
|
import app.organicmaps.editor.LanguagesFragment;
|
||||||
import app.organicmaps.editor.ProfileActivity;
|
import app.organicmaps.editor.ProfileActivity;
|
||||||
@@ -35,7 +42,7 @@ import app.organicmaps.sdk.util.SharedPropertiesUtils;
|
|||||||
import app.organicmaps.sdk.util.log.LogsManager;
|
import app.organicmaps.sdk.util.log.LogsManager;
|
||||||
import app.organicmaps.util.ThemeSwitcher;
|
import app.organicmaps.util.ThemeSwitcher;
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -73,6 +80,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
|
|||||||
initScreenSleepEnabledPrefsCallbacks();
|
initScreenSleepEnabledPrefsCallbacks();
|
||||||
initShowOnLockScreenPrefsCallbacks();
|
initShowOnLockScreenPrefsCallbacks();
|
||||||
initLeftButtonPrefs();
|
initLeftButtonPrefs();
|
||||||
|
initCustomMapDownloadUrlPrefsCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initLeftButtonPrefs()
|
private void initLeftButtonPrefs()
|
||||||
@@ -486,7 +494,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
|
|||||||
pref.setOnPreferenceClickListener(preference -> {
|
pref.setOnPreferenceClickListener(preference -> {
|
||||||
if (MapManager.nativeIsDownloading())
|
if (MapManager.nativeIsDownloading())
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.downloading_is_active)
|
.setTitle(R.string.downloading_is_active)
|
||||||
.setMessage(R.string.cant_change_this_setting)
|
.setMessage(R.string.cant_change_this_setting)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
@@ -535,6 +543,34 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initCustomMapDownloadUrlPrefsCallbacks()
|
||||||
|
{
|
||||||
|
Preference customUrlPref = getPreference(getString(R.string.pref_custom_map_download_url));
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
|
||||||
|
|
||||||
|
String current = prefs.getString(getString(R.string.pref_custom_map_download_url), "");
|
||||||
|
String normalizedUrl = Framework.normalizeServerUrl(current);
|
||||||
|
|
||||||
|
// Initial summary
|
||||||
|
customUrlPref.setSummary(normalizedUrl.isEmpty()
|
||||||
|
? getString(R.string.download_resources_custom_url_summary_none)
|
||||||
|
: normalizedUrl);
|
||||||
|
|
||||||
|
// Sync native
|
||||||
|
Framework.applyCustomMapDownloadUrl(requireContext(), normalizedUrl);
|
||||||
|
|
||||||
|
// Show dialog
|
||||||
|
customUrlPref.setOnPreferenceClickListener(preference -> {
|
||||||
|
CustomMapServerDialog.show(requireContext(), url -> {
|
||||||
|
preference.setSummary(url.isEmpty()
|
||||||
|
? getString(R.string.download_resources_custom_url_summary_none)
|
||||||
|
: url);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void removePreference(@NonNull String categoryKey, @NonNull Preference preference)
|
private void removePreference(@NonNull String categoryKey, @NonNull Preference preference)
|
||||||
{
|
{
|
||||||
final PreferenceCategory category = getPreference(categoryKey);
|
final PreferenceCategory category = getPreference(categoryKey);
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public class StoragePathFragment extends BaseSettingsFragment
|
|||||||
final String oldPath = storages.get(currentIndex).mPath;
|
final String oldPath = storages.get(currentIndex).mPath;
|
||||||
final String newPath = storages.get(newIndex).mPath;
|
final String newPath = storages.get(newIndex).mPath;
|
||||||
|
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setTitle(R.string.move_maps)
|
.setTitle(R.string.move_maps)
|
||||||
.setPositiveButton(R.string.ok, (dlg, which) -> moveStorage(newPath, oldPath))
|
.setPositiveButton(R.string.ok, (dlg, which) -> moveStorage(newPath, oldPath))
|
||||||
@@ -133,7 +133,7 @@ public class StoragePathFragment extends BaseSettingsFragment
|
|||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.move_maps_error)
|
.setTitle(R.string.move_maps_error)
|
||||||
.setPositiveButton(
|
.setPositiveButton(
|
||||||
R.string.report_a_bug,
|
R.string.report_a_bug,
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ public enum ThemeSwitcher
|
|||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
||||||
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_YES);
|
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_YES);
|
||||||
else
|
|
||||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||||
|
|
||||||
if (RoutingController.get().isVehicleNavigation())
|
if (RoutingController.get().isVehicleNavigation())
|
||||||
@@ -104,7 +103,6 @@ public enum ThemeSwitcher
|
|||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
||||||
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_NO);
|
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_NO);
|
||||||
else
|
|
||||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
|
||||||
|
|
||||||
if (RoutingController.get().isVehicleNavigation())
|
if (RoutingController.get().isVehicleNavigation())
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import androidx.annotation.ColorInt;
|
|||||||
import androidx.annotation.IdRes;
|
import androidx.annotation.IdRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.core.content.res.ResourcesCompat;
|
import androidx.core.content.res.ResourcesCompat;
|
||||||
import androidx.core.graphics.Insets;
|
import androidx.core.graphics.Insets;
|
||||||
import androidx.core.view.WindowCompat;
|
import androidx.core.view.WindowCompat;
|
||||||
@@ -196,7 +195,7 @@ public final class UiUtils
|
|||||||
public static void showHomeUpButton(MaterialToolbar toolbar)
|
public static void showHomeUpButton(MaterialToolbar toolbar)
|
||||||
{
|
{
|
||||||
toolbar.setNavigationIcon(
|
toolbar.setNavigationIcon(
|
||||||
ThemeUtils.getResource(toolbar.getContext(), androidx.appcompat.R.attr.homeAsUpIndicator));
|
UiUtils.getStyledResourceId(toolbar.getContext(), androidx.appcompat.R.attr.homeAsUpIndicator));
|
||||||
}
|
}
|
||||||
|
|
||||||
// this method returns the total height of the display (in pixels) including notch and other touchable areas
|
// this method returns the total height of the display (in pixels) including notch and other touchable areas
|
||||||
@@ -209,15 +208,7 @@ public final class UiUtils
|
|||||||
}
|
}
|
||||||
public static void setInputError(@NonNull TextInputLayout layout, @StringRes int error)
|
public static void setInputError(@NonNull TextInputLayout layout, @StringRes int error)
|
||||||
{
|
{
|
||||||
setInputError(layout, error == 0 ? null : layout.getContext().getString(error));
|
layout.setError(error == 0 ? null : layout.getContext().getString(error));
|
||||||
}
|
|
||||||
|
|
||||||
public static void setInputError(@NonNull TextInputLayout layout, String error)
|
|
||||||
{
|
|
||||||
layout.getEditText().setError(error);
|
|
||||||
layout.getEditText().setTextColor(error == null
|
|
||||||
? ThemeUtils.getColor(layout.getContext(), android.R.attr.textColorPrimary)
|
|
||||||
: ContextCompat.getColor(layout.getContext(), R.color.base_red));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setFullscreen(@NonNull Activity activity, boolean fullscreen)
|
public static void setFullscreen(@NonNull Activity activity, boolean fullscreen)
|
||||||
@@ -281,6 +272,14 @@ public final class UiUtils
|
|||||||
view.setPadding(systemInsets.left, systemInsets.top, systemInsets.right, view.getPaddingBottom());
|
view.setPadding(systemInsets.left, systemInsets.top, systemInsets.right, view.getPaddingBottom());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setViewNavigationTopInsetsMargin(View view, WindowInsetsCompat windowInsets)
|
||||||
|
{
|
||||||
|
final Insets systemInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
|
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
|
||||||
|
lp.topMargin = systemInsets.top;
|
||||||
|
view.setLayoutParams(lp);
|
||||||
|
}
|
||||||
|
|
||||||
public static void setupNavigationIcon(@NonNull MaterialToolbar toolbar, @NonNull View.OnClickListener listener)
|
public static void setupNavigationIcon(@NonNull MaterialToolbar toolbar, @NonNull View.OnClickListener listener)
|
||||||
{
|
{
|
||||||
View customNavigationButton = toolbar.findViewById(R.id.back);
|
View customNavigationButton = toolbar.findViewById(R.id.back);
|
||||||
|
|||||||
@@ -8,20 +8,19 @@ import android.graphics.Typeface;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
public abstract class BaseSignView extends View
|
public abstract class BaseSignView extends View
|
||||||
{
|
{
|
||||||
private float mBorderWidthRatio = 0.1f;
|
private float mBorderWidthRatio = 0.1f;
|
||||||
protected void setBorderWidthRatio(float ratio)
|
protected void setBorderWidthRatio(float ratio) {
|
||||||
{
|
|
||||||
mBorderWidthRatio = ratio;
|
mBorderWidthRatio = ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float mBorderInsetRatio = 0f;
|
private float mBorderInsetRatio = 0f;
|
||||||
protected void setBorderInsetRatio(float ratio)
|
protected void setBorderInsetRatio(float ratio) {
|
||||||
{
|
|
||||||
mBorderInsetRatio = ratio;
|
mBorderInsetRatio = ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +54,11 @@ public abstract class BaseSignView extends View
|
|||||||
mTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
|
mTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setColors(int backgroundColor, int borderColor, int alertColor, int textColor, int textAlertColor)
|
protected void setColors(int backgroundColor,
|
||||||
|
int borderColor,
|
||||||
|
int alertColor,
|
||||||
|
int textColor,
|
||||||
|
int textAlertColor)
|
||||||
{
|
{
|
||||||
mBackgroundColor = backgroundColor;
|
mBackgroundColor = backgroundColor;
|
||||||
mBorderColor = borderColor;
|
mBorderColor = borderColor;
|
||||||
@@ -69,8 +72,7 @@ public abstract class BaseSignView extends View
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight)
|
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
|
||||||
{
|
|
||||||
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
||||||
final float paddingX = getPaddingLeft() + getPaddingRight();
|
final float paddingX = getPaddingLeft() + getPaddingRight();
|
||||||
final float paddingY = getPaddingTop() + getPaddingBottom();
|
final float paddingY = getPaddingTop() + getPaddingBottom();
|
||||||
@@ -89,8 +91,7 @@ public abstract class BaseSignView extends View
|
|||||||
{
|
{
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
final String str = getValueString();
|
final String str = getValueString();
|
||||||
if (str == null)
|
if (str == null) return;
|
||||||
return;
|
|
||||||
|
|
||||||
final float cx = mWidth / 2f;
|
final float cx = mWidth / 2f;
|
||||||
final float cy = mHeight / 2f;
|
final float cy = mHeight / 2f;
|
||||||
@@ -142,8 +143,7 @@ public abstract class BaseSignView extends View
|
|||||||
void configureTextSize()
|
void configureTextSize()
|
||||||
{
|
{
|
||||||
String text = getValueString();
|
String text = getValueString();
|
||||||
if (text == null)
|
if (text == null) return;
|
||||||
return;
|
|
||||||
final float textRadius = mBorderRadius - mBorderWidth;
|
final float textRadius = mBorderRadius - mBorderWidth;
|
||||||
final float maxTextSize = 2f * textRadius;
|
final float maxTextSize = 2f * textRadius;
|
||||||
final float maxTextSize2 = maxTextSize * maxTextSize;
|
final float maxTextSize2 = maxTextSize * maxTextSize;
|
||||||
@@ -154,7 +154,7 @@ public abstract class BaseSignView extends View
|
|||||||
sz = (lo + hi) / 2f;
|
sz = (lo + hi) / 2f;
|
||||||
mTextPaint.setTextSize(sz);
|
mTextPaint.setTextSize(sz);
|
||||||
mTextPaint.getTextBounds(text, 0, text.length(), b);
|
mTextPaint.getTextBounds(text, 0, text.length(), b);
|
||||||
float area = b.width() * b.width() + b.height() * b.height();
|
float area = b.width()*b.width() + b.height()*b.height();
|
||||||
if (area <= maxTextSize2)
|
if (area <= maxTextSize2)
|
||||||
lo = sz + 1f;
|
lo = sz + 1f;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import android.content.Context;
|
|||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.util.StringUtils;
|
import app.organicmaps.sdk.util.StringUtils;
|
||||||
|
|
||||||
@@ -20,8 +22,8 @@ public class CurrentSpeedView extends BaseSignView
|
|||||||
setBorderWidthRatio(0.1f);
|
setBorderWidthRatio(0.1f);
|
||||||
setBorderInsetRatio(0.05f);
|
setBorderInsetRatio(0.05f);
|
||||||
|
|
||||||
try (TypedArray a = ctx.getTheme().obtainStyledAttributes(
|
try (TypedArray a = ctx.getTheme()
|
||||||
attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */, 0, 0))
|
.obtainStyledAttributes(attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */ , 0, 0))
|
||||||
{
|
{
|
||||||
int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR);
|
int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR);
|
||||||
int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR);
|
int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR);
|
||||||
@@ -31,7 +33,7 @@ public class CurrentSpeedView extends BaseSignView
|
|||||||
if (isInEditMode())
|
if (isInEditMode())
|
||||||
{
|
{
|
||||||
mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50);
|
mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50);
|
||||||
mSpeedStr = Integer.toString((int) mSpeedMps);
|
mSpeedStr = Integer.toString((int)mSpeedMps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,7 +47,7 @@ public class CurrentSpeedView extends BaseSignView
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Pair<String, String> su = StringUtils.nativeFormatSpeedAndUnits(mps);
|
Pair<String,String> su = StringUtils.nativeFormatSpeedAndUnits(mps);
|
||||||
mSpeedStr = su.first;
|
mSpeedStr = su.first;
|
||||||
}
|
}
|
||||||
requestLayout();
|
requestLayout();
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import app.organicmaps.R;
|
|
||||||
import app.organicmaps.util.UiUtils;
|
|
||||||
import com.google.android.material.imageview.ShapeableImageView;
|
import com.google.android.material.imageview.ShapeableImageView;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
|
import app.organicmaps.R;
|
||||||
|
import app.organicmaps.util.UiUtils;
|
||||||
|
|
||||||
public class PlaceholderView extends LinearLayout
|
public class PlaceholderView extends LinearLayout
|
||||||
{
|
{
|
||||||
@SuppressWarnings("NullableProblems")
|
@SuppressWarnings("NullableProblems")
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import android.content.res.TypedArray;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
|
|
||||||
public class SpeedLimitView extends BaseSignView
|
public class SpeedLimitView extends BaseSignView
|
||||||
@@ -25,22 +27,15 @@ public class SpeedLimitView extends BaseSignView
|
|||||||
|
|
||||||
try (TypedArray styleAttrs = ctx.getTheme().obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0))
|
try (TypedArray styleAttrs = ctx.getTheme().obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0))
|
||||||
{
|
{
|
||||||
final int bgColor =
|
final int bgColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR);
|
||||||
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR);
|
final int borderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR);
|
||||||
final int borderColor =
|
final int alertColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR);
|
||||||
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR);
|
final int textColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR);
|
||||||
final int alertColor =
|
final int txtAlertColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR);
|
||||||
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR);
|
|
||||||
final int textColor =
|
|
||||||
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR);
|
|
||||||
final int txtAlertColor =
|
|
||||||
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR);
|
|
||||||
setColors(bgColor, borderColor, alertColor, textColor, txtAlertColor);
|
setColors(bgColor, borderColor, alertColor, textColor, txtAlertColor);
|
||||||
|
|
||||||
unlimitedBorderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor,
|
unlimitedBorderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor, DefaultValues.UNLIMITED_BORDER_COLOR);
|
||||||
DefaultValues.UNLIMITED_BORDER_COLOR);
|
unlimitedStripeColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor, DefaultValues.UNLIMITED_STRIPE_COLOR);
|
||||||
unlimitedStripeColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor,
|
|
||||||
DefaultValues.UNLIMITED_STRIPE_COLOR);
|
|
||||||
|
|
||||||
if (isInEditMode())
|
if (isInEditMode())
|
||||||
{
|
{
|
||||||
@@ -80,7 +75,7 @@ public class SpeedLimitView extends BaseSignView
|
|||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas)
|
protected void onDraw(Canvas canvas)
|
||||||
{
|
{
|
||||||
final float cx = mWidth / 2f, cy = mHeight / 2f;
|
final float cx = mWidth/2f, cy = mHeight/2f;
|
||||||
|
|
||||||
if (mSpeedLimit == 0) // 0 means unlimited speed (maxspeed=none)
|
if (mSpeedLimit == 0) // 0 means unlimited speed (maxspeed=none)
|
||||||
{
|
{
|
||||||
@@ -110,7 +105,7 @@ public class SpeedLimitView extends BaseSignView
|
|||||||
stripe.setStrokeWidth(mBorderWidth * 0.4f);
|
stripe.setStrokeWidth(mBorderWidth * 0.4f);
|
||||||
|
|
||||||
final float radius = mRadius * 0.8f; // Shorten to 80% of full radius
|
final float radius = mRadius * 0.8f; // Shorten to 80% of full radius
|
||||||
final float diag = (float) (1 / Math.sqrt(2)); // 45 degrees
|
final float diag = (float) (1/Math.sqrt(2)); // 45 degrees
|
||||||
final float dx = -diag, dy = +diag;
|
final float dx = -diag, dy = +diag;
|
||||||
final float px = -dy, py = +dx; // Perpendicular
|
final float px = -dy, py = +dx; // Perpendicular
|
||||||
final float step = radius * 0.15f; // Spacing
|
final float step = radius * 0.15f; // Spacing
|
||||||
@@ -127,6 +122,7 @@ public class SpeedLimitView extends BaseSignView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private interface DefaultValues
|
private interface DefaultValues
|
||||||
{
|
{
|
||||||
int BACKGROUND_COLOR = 0xFFFFFFFF;
|
int BACKGROUND_COLOR = 0xFFFFFFFF;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package app.organicmaps.widget.placepage;
|
package app.organicmaps.widget.placepage;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import app.organicmaps.sdk.util.StringUtils;
|
import app.organicmaps.sdk.util.StringUtils;
|
||||||
import com.github.mikephil.charting.charts.BarLineChartBase;
|
import com.github.mikephil.charting.charts.BarLineChartBase;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import com.github.mikephil.charting.components.AxisBase;
|
import com.github.mikephil.charting.components.AxisBase;
|
||||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class BookmarkColorDialogFragment extends BaseMwmDialogFragment
|
|||||||
mIconResId = getArguments().getInt(ICON_RES);
|
mIconResId = getArguments().getInt(ICON_RES);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
return new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setView(buildView())
|
.setView(buildView())
|
||||||
.setTitle(R.string.choose_color)
|
.setTitle(R.string.choose_color)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
|||||||
@@ -105,8 +105,7 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
|
|||||||
public EditBookmarkFragment() {}
|
public EditBookmarkFragment() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState)
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
{
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setStyle(DialogFragment.STYLE_NORMAL, R.style.MwmTheme_FullScreenDialog);
|
setStyle(DialogFragment.STYLE_NORMAL, R.style.MwmTheme_FullScreenDialog);
|
||||||
}
|
}
|
||||||
@@ -185,9 +184,10 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
|
|||||||
{
|
{
|
||||||
super.onStart();
|
super.onStart();
|
||||||
Dialog dialog = getDialog();
|
Dialog dialog = getDialog();
|
||||||
if (dialog != null)
|
if (dialog != null) {
|
||||||
{
|
dialog.getWindow().setLayout(
|
||||||
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focus name and show keyboard for "Unknown Place" bookmarks
|
// Focus name and show keyboard for "Unknown Place" bookmarks
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import android.widget.RelativeLayout;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.widget.NestedScrollView;
|
import androidx.core.widget.NestedScrollView;
|
||||||
|
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import app.organicmaps.ChartController;
|
import app.organicmaps.ChartController;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.Framework;
|
import app.organicmaps.sdk.Framework;
|
||||||
@@ -14,7 +17,6 @@ import app.organicmaps.sdk.bookmarks.data.Track;
|
|||||||
import app.organicmaps.sdk.bookmarks.data.TrackStatistics;
|
import app.organicmaps.sdk.bookmarks.data.TrackStatistics;
|
||||||
import app.organicmaps.util.UiUtils;
|
import app.organicmaps.util.UiUtils;
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ElevationProfileViewRenderer implements PlacePageStateListener
|
public class ElevationProfileViewRenderer implements PlacePageStateListener
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ public class OpenStateTextFormatter
|
|||||||
return String.format(Locale.ROOT, "%02d:%02d", hour, minute);
|
return String.format(Locale.ROOT, "%02d:%02d", hour, minute);
|
||||||
|
|
||||||
int h = hour % 12;
|
int h = hour % 12;
|
||||||
if (h == 0)
|
if (h == 0) h = 12;
|
||||||
h = 12;
|
|
||||||
String ampm = (hour < 12) ? "AM" : "PM";
|
String ampm = (hour < 12) ? "AM" : "PM";
|
||||||
return String.format(Locale.ROOT, "%d:%02d %s", h, minute, ampm);
|
return String.format(Locale.ROOT, "%d:%02d %s", h, minute, ampm);
|
||||||
}
|
}
|
||||||
@@ -30,8 +29,16 @@ public class OpenStateTextFormatter
|
|||||||
return t.getDayOfWeek().getDisplayName(TextStyle.SHORT, locale);
|
return t.getDayOfWeek().getDisplayName(TextStyle.SHORT, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String buildAtLabel(boolean opens, boolean isToday, String dayShort, String time, String opensAtLocalized,
|
static String buildAtLabel(
|
||||||
String closesAtLocalized, String opensDayAtLocalized, String closesDayAtLocalized)
|
boolean opens,
|
||||||
|
boolean isToday,
|
||||||
|
String dayShort,
|
||||||
|
String time,
|
||||||
|
String opensAtLocalized,
|
||||||
|
String closesAtLocalized,
|
||||||
|
String opensDayAtLocalized,
|
||||||
|
String closesDayAtLocalized
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (isToday)
|
if (isToday)
|
||||||
return opens ? String.format(Locale.ROOT, opensAtLocalized, time) // Opens at %s
|
return opens ? String.format(Locale.ROOT, opensAtLocalized, time) // Opens at %s
|
||||||
|
|||||||
@@ -464,7 +464,7 @@ public class PlacePageController
|
|||||||
mAlertDialog.show();
|
mAlertDialog.show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAlertDialog = new MaterialAlertDialogBuilder(requireContext(), R.style.MwmTheme_AlertDialog)
|
mAlertDialog = new MaterialAlertDialogBuilder(requireContext())
|
||||||
.setTitle(requireContext().getString(R.string.delete_track_dialog_title, mMapObject.getTitle()))
|
.setTitle(requireContext().getString(R.string.delete_track_dialog_title, mMapObject.getTitle()))
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import androidx.fragment.app.FragmentFactory;
|
|||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import app.organicmaps.MwmActivity;
|
import app.organicmaps.MwmActivity;
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
@@ -691,6 +692,7 @@ public class PlacePageView extends Fragment
|
|||||||
{
|
{
|
||||||
UiUtils.showIf(Editor.nativeShouldShowEditPlace(), mEditPlace);
|
UiUtils.showIf(Editor.nativeShouldShowEditPlace(), mEditPlace);
|
||||||
UiUtils.showIf(Editor.nativeShouldShowAddPlace(), mAddPlace);
|
UiUtils.showIf(Editor.nativeShouldShowAddPlace(), mAddPlace);
|
||||||
|
UiUtils.hide(mMapTooOld);
|
||||||
MaterialButton mTvEditPlace = mEditPlace.findViewById(R.id.mb__place_editor);
|
MaterialButton mTvEditPlace = mEditPlace.findViewById(R.id.mb__place_editor);
|
||||||
MaterialButton mTvAddPlace = mAddPlace.findViewById(R.id.mb__place_add);
|
MaterialButton mTvAddPlace = mAddPlace.findViewById(R.id.mb__place_add);
|
||||||
|
|
||||||
@@ -698,39 +700,57 @@ public class PlacePageView extends Fragment
|
|||||||
|
|
||||||
if (shouldEnableEditPlace)
|
if (shouldEnableEditPlace)
|
||||||
{
|
{
|
||||||
|
mTvEditPlace.setEnabled(true);
|
||||||
|
mTvAddPlace.setEnabled(true);
|
||||||
mTvEditPlace.setOnClickListener(this);
|
mTvEditPlace.setOnClickListener(this);
|
||||||
mTvAddPlace.setOnClickListener(this);
|
mTvAddPlace.setOnClickListener(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mTvEditPlace.setOnClickListener(
|
String countryId = MapManager.nativeGetSelectedCountry();
|
||||||
(v) -> { Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); });
|
|
||||||
mTvAddPlace.setOnClickListener(
|
|
||||||
(v) -> { Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); });
|
|
||||||
|
|
||||||
CountryItem map = CountryItem.fill(MapManager.nativeGetSelectedCountry());
|
if (countryId != null && MapManager.nativeIsMapTooOldToEdit(countryId))
|
||||||
|
{
|
||||||
|
// map editing is disabled because the map is too old
|
||||||
|
mTvEditPlace.setEnabled(true);
|
||||||
|
mTvAddPlace.setEnabled(true);
|
||||||
|
mTvEditPlace.setOnClickListener((v) -> {
|
||||||
|
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
|
||||||
|
});
|
||||||
|
mTvAddPlace.setOnClickListener((v) -> {
|
||||||
|
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
|
||||||
|
});
|
||||||
|
|
||||||
|
CountryItem map = CountryItem.fill(countryId);
|
||||||
|
|
||||||
if (map.status == CountryItem.STATUS_UPDATABLE || map.status == CountryItem.STATUS_DONE
|
if (map.status == CountryItem.STATUS_UPDATABLE || map.status == CountryItem.STATUS_DONE
|
||||||
|| map.status == CountryItem.STATUS_FAILED)
|
|| map.status == CountryItem.STATUS_FAILED)
|
||||||
{
|
{
|
||||||
mMapTooOld.setVisibility(VISIBLE);
|
UiUtils.show(mMapTooOld);
|
||||||
MaterialButton mTvUpdateTooOldMap = mMapTooOld.findViewById(R.id.mb__update_too_old_map);
|
|
||||||
boolean canUpdateMap = map.status != CountryItem.STATUS_DONE;
|
|
||||||
|
|
||||||
|
boolean canUpdateMap = map.status != CountryItem.STATUS_DONE;
|
||||||
|
MaterialButton mTvUpdateTooOldMap = mMapTooOld.findViewById(R.id.mb__update_too_old_map);
|
||||||
|
UiUtils.showIf(canUpdateMap, mTvUpdateTooOldMap);
|
||||||
|
|
||||||
|
MaterialTextView mapTooOldDescription = mMapTooOld.findViewById(R.id.tv__map_too_old_description);
|
||||||
if (canUpdateMap)
|
if (canUpdateMap)
|
||||||
{
|
{
|
||||||
|
mapTooOldDescription.setText(R.string.place_page_map_too_old_description);
|
||||||
mTvUpdateTooOldMap.setOnClickListener((v) -> {
|
mTvUpdateTooOldMap.setOnClickListener((v) -> {
|
||||||
MapManagerHelper.warn3gAndDownload(requireActivity(), map.id, null);
|
MapManagerHelper.warn3gAndDownload(requireActivity(), map.id, null);
|
||||||
mMapTooOld.setVisibility(GONE);
|
UiUtils.hide(mMapTooOld);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
mTvUpdateTooOldMap.setVisibility(GONE);
|
|
||||||
MaterialTextView mapTooOldDescription = mMapTooOld.findViewById(R.id.tv__map_too_old_description);
|
|
||||||
mapTooOldDescription.setText(R.string.place_page_app_too_old_description);
|
mapTooOldDescription.setText(R.string.place_page_app_too_old_description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// map editing is disabled for other reasons
|
||||||
|
mTvEditPlace.setEnabled(false);
|
||||||
|
mTvAddPlace.setEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final int editButtonColor =
|
final int editButtonColor =
|
||||||
@@ -744,7 +764,9 @@ public class PlacePageView extends Fragment
|
|||||||
mTvAddPlace.setTextColor(editButtonColor);
|
mTvAddPlace.setTextColor(editButtonColor);
|
||||||
mTvEditPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
|
mTvEditPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
|
||||||
mTvAddPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
|
mTvAddPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
|
||||||
UiUtils.showIf(UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddPlace), mEditTopSpace);
|
UiUtils.showIf(
|
||||||
|
UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddPlace),
|
||||||
|
mEditTopSpace);
|
||||||
}
|
}
|
||||||
updateLinksView();
|
updateLinksView();
|
||||||
updateOpeningHoursView();
|
updateOpeningHoursView();
|
||||||
@@ -845,7 +867,8 @@ public class PlacePageView extends Fragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get colours
|
// Get colours
|
||||||
final ForegroundColorSpan colorGreen = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green));
|
final ForegroundColorSpan colorGreen =
|
||||||
|
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green));
|
||||||
final ForegroundColorSpan colorYellow =
|
final ForegroundColorSpan colorYellow =
|
||||||
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_yellow));
|
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_yellow));
|
||||||
final ForegroundColorSpan colorRed = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_red));
|
final ForegroundColorSpan colorRed = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_red));
|
||||||
@@ -873,12 +896,13 @@ public class PlacePageView extends Fragment
|
|||||||
if (nextStateTime > 0 && nextStateTime < Long.MAX_VALUE / 2)
|
if (nextStateTime > 0 && nextStateTime < Long.MAX_VALUE / 2)
|
||||||
{
|
{
|
||||||
// NOTE: Timezone is currently device timezone. TODO: use feature-specific timezone.
|
// NOTE: Timezone is currently device timezone. TODO: use feature-specific timezone.
|
||||||
nextChangeLocal = ZonedDateTime.ofInstant(Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault());
|
nextChangeLocal = ZonedDateTime.ofInstant(
|
||||||
|
Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault()
|
||||||
|
);
|
||||||
hasFiniteNextChange = true;
|
hasFiniteNextChange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable ignored)
|
catch (Throwable ignored) {}
|
||||||
{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasFiniteNextChange) // No valid next change
|
if (!hasFiniteNextChange) // No valid next change
|
||||||
@@ -918,14 +942,16 @@ public class PlacePageView extends Fragment
|
|||||||
final boolean isToday =
|
final boolean isToday =
|
||||||
OpenStateTextFormatter.isSameLocalDate(nextChangeLocal, ZonedDateTime.now(nextChangeLocal.getZone()));
|
OpenStateTextFormatter.isSameLocalDate(nextChangeLocal, ZonedDateTime.now(nextChangeLocal.getZone()));
|
||||||
// Full weekday name per design feedback.
|
// Full weekday name per design feedback.
|
||||||
final String dayName = nextChangeLocal.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
|
final String dayName =
|
||||||
|
nextChangeLocal.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
|
||||||
|
|
||||||
if (isOpen) // > 60 minutes OR negative (safety). Show “Open now • Closes at 18:00”
|
if (isOpen) // > 60 minutes OR negative (safety). Show “Open now • Closes at 18:00”
|
||||||
{
|
{
|
||||||
openStateString.append(getString(R.string.open_now), colorGreen, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
openStateString.append(getString(R.string.open_now), colorGreen, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
final String atLabel = OpenStateTextFormatter.buildAtLabel(
|
final String atLabel =
|
||||||
false, isToday, dayName, localizedTimeString, opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
|
OpenStateTextFormatter.buildAtLabel(false, isToday, dayName, localizedTimeString,
|
||||||
|
opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(atLabel))
|
if (!TextUtils.isEmpty(atLabel))
|
||||||
openStateString.append(" • ").append(atLabel);
|
openStateString.append(" • ").append(atLabel);
|
||||||
@@ -934,8 +960,9 @@ public class PlacePageView extends Fragment
|
|||||||
{
|
{
|
||||||
openStateString.append(getString(R.string.closed_now), colorRed, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
openStateString.append(getString(R.string.closed_now), colorRed, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
final String atLabel = OpenStateTextFormatter.buildAtLabel(
|
final String atLabel =
|
||||||
true, isToday, dayName, localizedTimeString, opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
|
OpenStateTextFormatter.buildAtLabel(true, isToday, dayName, localizedTimeString,
|
||||||
|
opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(atLabel))
|
if (!TextUtils.isEmpty(atLabel))
|
||||||
openStateString.append(" • ").append(atLabel);
|
openStateString.append(" • ").append(atLabel);
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package app.organicmaps.widget.placepage;
|
|||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PlacePageViewModel extends ViewModel
|
public class PlacePageViewModel extends ViewModel
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ import app.organicmaps.widget.placepage.PlacePageViewModel;
|
|||||||
import com.google.android.material.textview.MaterialTextView;
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
public class PlacePageBookmarkFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener,
|
public class PlacePageBookmarkFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener,
|
||||||
Observer<MapObject>,
|
Observer<MapObject>, EditBookmarkFragment.EditBookmarkListener
|
||||||
EditBookmarkFragment.EditBookmarkListener
|
|
||||||
{
|
{
|
||||||
private View mFrame;
|
private View mFrame;
|
||||||
private MaterialTextView mTvBookmarkNote;
|
private MaterialTextView mTvBookmarkNote;
|
||||||
|
|||||||
@@ -13,13 +13,15 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import com.google.android.material.imageview.ShapeableImageView;
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.Framework;
|
import app.organicmaps.sdk.Framework;
|
||||||
import app.organicmaps.sdk.bookmarks.data.ChargeSocketDescriptor;
|
import app.organicmaps.sdk.bookmarks.data.ChargeSocketDescriptor;
|
||||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||||
import app.organicmaps.widget.placepage.PlacePageViewModel;
|
import app.organicmaps.widget.placepage.PlacePageViewModel;
|
||||||
import com.google.android.material.imageview.ShapeableImageView;
|
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
public class PlacePageChargeSocketsFragment extends Fragment implements Observer<MapObject>
|
public class PlacePageChargeSocketsFragment extends Fragment implements Observer<MapObject>
|
||||||
@@ -94,8 +96,8 @@ public class PlacePageChargeSocketsFragment extends Fragment implements Observer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DiscouragedApi")
|
@SuppressLint("DiscouragedApi")
|
||||||
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
|
int resTypeId =
|
||||||
requireContext().getPackageName());
|
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
|
||||||
if (resTypeId != 0)
|
if (resTypeId != 0)
|
||||||
{
|
{
|
||||||
type.setText(resTypeId);
|
type.setText(resTypeId);
|
||||||
@@ -106,8 +108,7 @@ public class PlacePageChargeSocketsFragment extends Fragment implements Observer
|
|||||||
DecimalFormat df = new DecimalFormat("#.##");
|
DecimalFormat df = new DecimalFormat("#.##");
|
||||||
power.setText(getString(R.string.kw_label, df.format(socket.power())));
|
power.setText(getString(R.string.kw_label, df.format(socket.power())));
|
||||||
}
|
}
|
||||||
else if (socket.ignorePower())
|
else if (socket.ignorePower()) {
|
||||||
{
|
|
||||||
power.setVisibility(INVISIBLE);
|
power.setVisibility(INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -192,8 +192,7 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
|
|||||||
default -> mMapObject.getMetadata(type);
|
default -> mMapObject.getMetadata(type);
|
||||||
};
|
};
|
||||||
// Add user names for social media if available
|
// Add user names for social media if available
|
||||||
if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/"))
|
if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/")) items.add(title);
|
||||||
items.add(title);
|
|
||||||
|
|
||||||
if (items.size() == 1)
|
if (items.size() == 1)
|
||||||
PlacePageUtils.copyToClipboard(requireContext(), mFrame, items.get(0));
|
PlacePageUtils.copyToClipboard(requireContext(), mFrame, items.get(0));
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
android:color="?colorControlHighlight">
|
android:color="?colorControlHighlight">
|
||||||
<item>
|
<item>
|
||||||
<shape>
|
<shape>
|
||||||
<solid android:color="?cardBackground" />
|
<solid android:color="?appBackground" />
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
<item android:id="@android:id/mask">
|
<item android:id="@android:id/mask">
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<shape
|
<shape
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
<solid android:color="@color/bg_panel"/>
|
<solid android:color="@color/bg_window"/>
|
||||||
<corners android:radius="100dp"/>
|
<corners android:radius="100dp"/>
|
||||||
</shape>
|
</shape>
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
<shape
|
<shape
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:shape="oval">
|
android:shape="oval">
|
||||||
<solid android:color="@color/bg_panel"/>
|
<solid android:color="@color/bg_window"/>
|
||||||
</shape>
|
</shape>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="960"
|
android:viewportWidth="960"
|
||||||
android:viewportHeight="960"
|
android:viewportHeight="960"
|
||||||
android:tint="?colorControlNormal">
|
android:tint="?iconTint">
|
||||||
<path
|
<path
|
||||||
android:pathData="M80,360v-160q0,-33 23.5,-56.5T160,120h640q33,0 56.5,23.5T880,200v160h-80v-160L160,200v160L80,360ZM160,720q-33,0 -56.5,-23.5T80,640v-200h80v200h640v-200h80v200q0,33 -23.5,56.5T800,720L160,720ZM40,840v-80h880v80L40,840ZM480,420ZM80,440v-80h240q11,0 21,6t15,16l47,93 123,-215q5,-9 14,-14.5t20,-5.5q11,0 21,5.5t15,16.5l49,98h235v80L620,440q-11,0 -21,-5.5T584,418l-26,-53 -123,215q-5,10 -15,15t-21,5q-11,0 -20.5,-6T364,578l-69,-138L80,440Z"
|
android:pathData="M80,360v-160q0,-33 23.5,-56.5T160,120h640q33,0 56.5,23.5T880,200v160h-80v-160L160,200v160L80,360ZM160,720q-33,0 -56.5,-23.5T80,640v-200h80v200h640v-200h80v200q0,33 -23.5,56.5T800,720L160,720ZM40,840v-80h880v80L40,840ZM480,420ZM80,440v-80h240q11,0 21,6t15,16l47,93 123,-215q5,-9 14,-14.5t20,-5.5q11,0 21,5.5t15,16.5l49,98h235v80L620,440q-11,0 -21,-5.5T584,418l-26,-53 -123,215q-5,10 -15,15t-21,5q-11,0 -20.5,-6T364,578l-69,-138L80,440Z"
|
||||||
android:fillColor="#fff"/>
|
android:fillColor="#fff"/>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user