Skip to content

Commit abfb1d8

Browse files
committed
Move documentation website from KeyMapper repo
1 parent 6a4ce34 commit abfb1d8

119 files changed

Lines changed: 2892 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-mkdocs.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Build mkdocs
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- main
8+
permissions:
9+
contents: write
10+
jobs:
11+
deploy:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: actions/setup-python@v4
16+
with:
17+
python-version: 3.x
18+
- uses: actions/cache@v3
19+
with:
20+
key: ${{ github.ref }}
21+
path: .cache
22+
- run: pip install mkdocs-material
23+
- run: pip install mkdocs-redirects
24+
- run: mkdocs gh-deploy --force

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,5 @@ cython_debug/
172172

173173
# PyPI configuration file
174174
.pypirc
175+
176+
*.DS_Store

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
# KeyMapperDocs
22
The mkdocs documentation website for the Key Mapper app. This used to be in the KeyMapper repo.
3+
4+
## Building
5+
6+
To build the documentation website you need to install [mkdocs-material](https://squidfunk.github.io/mkdocs-material/getting-started/) with Python. Just run `pip install -r requirements.txt` in the root of the project to install all the necessary dependencies. Then run `mkdocs serve` in the project root to run the server.

docs/CNAME

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docs.keymapper.club

docs/contributing/codebase.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Structure
2+
3+
This app follows something inspired from Clean Architecture and package-by-feature.
4+
5+
## Architecture
6+
7+
All data structures that are persisted are passed around as one of two objects:
8+
9+
1. **Non-Entity**. This models the data in a way that makes the code more readable and doing the business logic easier. There are no rules for how these need to be named. They should be named what they are. E.g KeyMap, Action, Constraint.
10+
11+
2. **Entity**. This models how the data should be stored. The class name has an ...Entity suffix. E.g KeyMapEntity. The data is more optimised for storing and the code required to get the data from these models isn't very concise or elegant. The developer took some strange decisions in the first versions of this app. 😆
12+
13+
Every screen in the app has a view model and the view model interacts with one or multiple *use cases* (more below). The view model converts data that needs to be shown to the user into something that can populate the user interface. For example, the data values in the Action object isn't very useful to the user so this needs to be converted into strings and images that do mean something to the user. All the view models have a ResourceProvider dependency which is how they get strings, Drawables and colours from the resources without having to use a Context. This isn't a problem for configuration changes (e.g locale change) because the activity is recreated, which means all the resources are re-fetched in the view model.
14+
15+
The use cases contains all the business logic in the app. A *use case* interacts with the adapters and repositories mentioned below. A use case is made for everything that can be done in the app. E.g configuring a key map, displaying a mapping, configuring settings, onboarding the user. Most use cases correspond to something that *the user can do* in the app but some do not because they contain complicated code that is used in multiple use cases. E.g the GetActionErrorUseCase which determines if an action can be performed successfully.
16+
17+
Adapters and repositories contain all interactions with the Android framework (except UI stuff). This is so that tests can be more easily written and executed. Android often changes what apps are allowed to do and how so abstracting these interactions away means the code only needs to be changed in a single place. This means that the only place that a Context object is used is in Services, Activities, Fragments and the adapters.
18+
19+
## Package by feature
20+
21+
Every package contains files related to each other. For example, everything (view models, fragments, use cases) to do with constraints is stored in one package.
22+
The only package which isn't a feature is the `data` package because it is useful to have some of the things in there together, e.g the migrations.
23+
The `system` package bundles all the packages which are related to the Android framework because there are so many.
24+
25+
![contributing-app-structure](../images/contributing-app-structure.png)
26+
27+
# Key event detection and input
28+
29+
The diagram below shows how key events are passed around Key Mapper on Android 14+. This change was required because in Android 14 Android restricted the rate at which intents can be broadcast to once per second when an app is backgrounded. This is too slow for repeating key event actions in Key Mapper. Key Mapper still uses broadcast receivers to send key events between the accessibility service and input method on older Android versions to reduce the chance of breaking everyone's key maps. As shown in the diagram this is a bit complicated and potentially over-engineered but it must be two-way and future proof to any further restrictions. Using manifest-defined broadcast receivers, that aren't rate limited isn't an elegant solution because one has to pass messages between these broadcast receivers and the services through some 3rd class. Binder is lower latency than using intents and is synchronous whereas broadcast receivers are asynchronous. Apps are not allowed to bind to accessibility services so a new "relay" service needed to be made to link the accessibility and input method services.
30+
31+
The accessibility service is where triggers are detected by listening to the key events that Android system sends it. Key event and text actions send their key events from the accessibility service to the relay service, which then forwards it to the input method.
32+
33+
The code for input methods to talk to the Key Event relay service can be found in KeyEventRelayServiceWrapper. Key events are listened to from the input method service when Android blocks key events to the accessibility service during phone calls.
34+
35+
![key-event-relay-service](../images/key-event-relay-service.svg)

docs/contributing/introduction.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
## Becoming a tester
2+
3+
You can get the apks for the pre-release versions in 2 ways:
4+
5+
1. Join [the Discord server](http://keymapper.club) and download the apks from the #testing-builds channel.
6+
2. Download the apk from GitHub Actions. This requires a GitHub account.
7+
You can get alpha builds [here](https://github.com/keymapperorg/KeyMapper/actions/workflows/android.yml) and beta builds [here](https://github.com/keymapperorg/KeyMapper/actions/workflows/android-release.yml).
8+
9+
Click on a 'workflow run' and then scroll down to see the 'artifacts'. If a build was successful then you can find the apk here.
10+
11+
!!! info
12+
All testing builds have `.ci.X` at the end of the version name where 'X' is a number is incremented every time a new build is made. Builds are made when a new feature or bug fix is implemented.
13+
14+
There are two types of pre-release versions:
15+
16+
- **Alpha**. These have ".alpha" in the version name and are the most unstable. Expect the most crashes and broken features in these builds. BEWARE! Your data in Key Mapper isn't considered compatible between alpha builds so it is possible Key Mapper will crash and refuse to fix itself if you update to a new build that can't understand the data.
17+
- **Beta**. These builds have some of the latest features and contain a few bugs. You can safely update between versions. These have ".beta.X" in the version name. These are pre-release builds for the the open-testing channel on Google Play and F-droid always has beta builds. When all known bugs are fixed a new build is released to the app stores.
18+
19+
### How can I help?
20+
- Test and experiment new features. All features and bug-fixes that are being worked on for a release can be found on the Projects page [here](https://github.com/keymapperorg/KeyMapper/projects).
21+
- If you find any bugs or crashes then report them by following the guide [here](../report-issues.md).
22+
23+
## Contributing code
24+
25+
### Setting up the environment
26+
27+
1. Fork the KeyMapper repository (repo).
28+
2. Clone the repo to your device. It will clone to a folder called KeyMapper by default.
29+
3. [Install](https://developer.android.com/studio/install) Android Studio if you don't have it already. It is available for Windows, Linux and macOS.
30+
4. Open the cloned KeyMapper folder in Android Studio. Install anything Android Studio prompts you to install. E.g the gradle wrapper version used by KeyMapper or older Android SDK versions.
31+
5. Create a new branch off develop which begins with "feature/" if it is a new feature or "fix/" if it is a bug fix. Then put a brief description of the feature/bug fix.
32+
6. Make any changes then commit them to your forked repo then make a pull request!
33+
34+
### Build flavors and types
35+
36+
After version 2.7.0 Key Mapper will have 2 build flavours: _free_ and _pro_. The pro flavor includes the closed-source features (e.g assistant trigger) and non-FOSS libraries such as the Google Play Billing library. The free variant stubs out these closed-source features and only uses FOSS libraries.
37+
38+
There are also 4 build types, which have different optimizations and package names.
39+
40+
- **debug** = This is the default debug build type that has no optimizations and builds rapidly. It has a `.debug` package name suffix.
41+
- **release** = This is the default release build type that includes a lot of optimizations and creates an apk/app bundle suitable for releasing. There is no package name suffix.
42+
- **debug_release** = This is a debug build type that does not include a package name suffix so that it is possible to test how the production app will look. It is the only way to get the Google Play Billing library functioning because it will break if the package name isn't the same as on the Play store.
43+
- **ci** = This is used for alpha builds to the community in Discord. It includes optimizations to dramatically shrink the apk size, improve performance, and has obfuscation. It has a `.ci` package name suffix.
44+
45+
### Branches 🌴
46+
47+
- master: Everything in the latest stable release.
48+
- develop: The most recent changes. The app is potentially unstable but it can be successfully compiled. A new release is branched off of here.
49+
- feature/*: Any new changes currently being developed. Merges into develop.
50+
- fix/*: A bug fix. This branch should be merged into a release branch and develop.
51+
52+
### Committing
53+
54+
Format:
55+
```
56+
<issue id> <type>: <subject>
57+
```
58+
59+
Every feature or bug fix commit should have an issue associated with it. This is a cue for the developer to plan what they are doing which improves efficiency. A feature should be split up into multiple tasks and each task should have its own commit. The feature should be developed on a separate branch and then merged into develop.
60+
61+
#### Example
62+
```
63+
#100 feat: This a new feature
64+
```
65+
66+
#### Types
67+
- feat: a new feature
68+
- fix: a bug fix
69+
- docs: changes to documentation
70+
- style: formatting, missing semi colons, etc; no code change
71+
- refactor: refactoring production code
72+
- test: adding tests, refactoring test; no production code change
73+
- chore: updating build tasks, package manager configs, version name changes, etc; no production code change
74+
- release: a new release.
75+
- website: stuff to do with the website.
76+
77+
The README, License, Credits, Changelog and Privacy Policy files should just be changed in the master branch.
78+
79+
### Versioning
80+
81+
This project uses semantic versioning. e.g 1.2.3-alpha.01
82+
83+
- 1st digit: major release. Only incremented when a big enough change happens to the project.
84+
- 2nd digit: minor releases. Incremented when a new feature or a few are added.
85+
- 3rd digit: patches. Incrememtend after a hotfix or bug fix.
86+
87+
Additional labels can be used as a suffix. e.g "alpha".
88+
89+
The version code in the develop branch should always be the highest. Therefore, when a new version is released in the release branch, it should be incremented as well.
90+
91+
### Releasing
92+
93+
Fastlane is used to partially automate the releasing process. Follow the [guide](https://docs.fastlane.tools/) on the Fastlane website to set it up.
94+
95+
#### Beta releases
96+
97+
##### Only for the first beta release
98+
1. Branch off develop into a new release branch (e.g release/2.3.0).
99+
2. Change the version name and version code in `version.properties` in the release branch.
100+
3. Change the version name and version code in `version.properties` in the develop branch to be one version ahead of the release branch.
101+
102+
##### For every release
103+
1. Manually edit CHANGELOG.md **in the develop branch** with *all* changes. Cherry pick this into the release branch.
104+
2. Open the KeyMapper folder in a terminal and run `fastlane beta`.
105+
3. Squash and merge the release branch into master. Then delete the release branch.
106+
107+
#### Production releases
108+
109+
1. Check that all translations are merged.
110+
2. Credit the translators in the About screen in the app and in the index.md on the documentation website.
111+
3. Manually edit CHANGELOG.md **in the develop branch** with *all* changes. Cherry pick this into the release branch.
112+
4. Open the KeyMapper folder in a terminal and run `fastlane prod`. This will release the production build to the
113+
open-testing track on Google Play. Once it is approved by Google Play you must promote the release from open testing
114+
to the production track in Google Play.
115+
5. Squash and merge the release branch into master. Then delete the release branch.
116+
117+
### Code Style
118+
119+
Follow Google's Kotlin style guide. [https://developer.android.com/kotlin/style-guide](https://developer.android.com/kotlin/style-guide)
120+
121+
## Translating 🌍
122+
123+
You can translate this project on the [CrowdIn page](https://crowdin.com/project/key-mapper). Translations will be
124+
merged into production once they are >80% translated. If your language isn't available on the CrowdIn page then contact
125+
the developer so we can add it. Our contact details are in the footer of every page on this site.
126+
127+
We really appreciate translators so thank you! 🙂
128+
129+
## Consistency Standards
130+
131+
### Writing
132+
133+
It is important to use consistent language within the app's code and documentation. Make sure that your submissions comply with these standards. If you have noticed inconsistencies you can alert the developer with [an issue](https://github.com/keymapperorg/KeyMapper/issues/new) or in [the Discord](http://keymapper.club). These standards don't need to be followed in places other than the documentation and source code. Follow this Material Design [guide](https://material.io/design/communication/writing.html).
134+
135+
#### Case
136+
137+
No title case unless it is the title of a webpage, section heading. No title case in the string resources in the source code at all.
138+
139+
Here are words and phrases that have been spelt inconsistently by the developer and everyone should follow these guidelines.
140+
141+
| Terminology | Correct 😍 | Incorrect 👿 |
142+
| --------------- | ------------------------------------------------------------ | ---------------------------------- |
143+
| The app's name. | **Key Mapper**<br />Use **Keyboard/Button Mapper** when advertising the app as this is how it appears in the app stores. You can use "Key Mapper" in the rest of the advert since this is much shorter. | key mapper, keymapper |
144+
| A key map | **key map**. KeyMap, keyMap in variable and class names. | keymap, Key Map. key-map. Key-Map. |
145+
| A trigger | **trigger** | Trigger |
146+
| An action | **action** | Action |
147+
| A constraint | **constraint** | Constraint |
148+
| A key event | **key event** | Key Event, keyevent |
149+
| A key code | **key code**. In variable and class names it should be keyCode instead of keycode. | keycode, Key Code |
150+
| A home screen | **home screen** | homescreen, Home Screen |
151+
| A backup/ to back up | Noun: **backup**. Verb; **back up** | Backup when using the verb. |
152+
153+
### Documentation
154+
155+
#### Headings
156+
157+
If a heading is for a particular feature then it should include the minimum supported Key Mapper version except version 2.0.
158+
159+
E.g "Trigger When Screen is Off (ROOT, 2.1.0+, Android 8.1+)" or "A feature (up to Android 10)".

0 commit comments

Comments
 (0)