mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-16 19:57:52 +01:00
214 lines
5.8 KiB
TypeScript
214 lines
5.8 KiB
TypeScript
/*
|
|
This file is part of the Notesnook project (https://notesnook.com/)
|
|
|
|
Copyright (C) 2023 Streetwriters (Private) Limited
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import { AndroidDevice, Page } from "@playwright/test";
|
|
import { DeviceSize } from "./device-utils";
|
|
|
|
export type Keyboard = {
|
|
name: string;
|
|
ime: string;
|
|
pkg: string;
|
|
layout: {
|
|
start: number;
|
|
end: number;
|
|
keyHeight: number;
|
|
keyWidth: number;
|
|
rowMargin: number;
|
|
specialKeyWidth: number;
|
|
spaceBarWidth: number;
|
|
rows: number;
|
|
};
|
|
};
|
|
|
|
const KEYBOARD_ROWS = [
|
|
"QWERTYUIOP".split(""),
|
|
["", ..."ASDFGHJKL".split(""), ""],
|
|
["SHIFT", ..."ZXCVBNM".split(""), "DEL"]
|
|
];
|
|
|
|
const SPECIAL_KEY_MAP = {
|
|
"\n": "Enter",
|
|
".": "Period",
|
|
" ": "Space"
|
|
} as const;
|
|
|
|
/**
|
|
* Pixels to device independent height (percentage based)
|
|
*/
|
|
function h(px: number) {
|
|
return px / 2460;
|
|
}
|
|
/**
|
|
* Pixels to device independent width (percentage based)
|
|
*/
|
|
function w(px: number) {
|
|
return px / 1080;
|
|
}
|
|
|
|
export const SUPPORTED_KEYBOARDS: Keyboard[] = [
|
|
{
|
|
name: "Gboard",
|
|
ime: "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME",
|
|
pkg: "com.google.android.inputmethod.latin",
|
|
|
|
layout: {
|
|
start: h(1700), //,
|
|
end: h(2300),
|
|
keyHeight: h(120),
|
|
keyWidth: w(100),
|
|
rowMargin: h(30),
|
|
specialKeyWidth: w(100 + 50),
|
|
spaceBarWidth: w(100 * 4),
|
|
rows: 4
|
|
}
|
|
},
|
|
{
|
|
name: "OpenBoard",
|
|
ime: "org.dslul.openboard.inputmethod.latin/.LatinIME",
|
|
pkg: "org.dslul.openboard.inputmethod.latin",
|
|
layout: {
|
|
start: h(1650),
|
|
end: h(2300),
|
|
keyHeight: h(110),
|
|
rowMargin: h(40),
|
|
keyWidth: w(100),
|
|
specialKeyWidth: w(100 + 50),
|
|
spaceBarWidth: w(100 * 4),
|
|
rows: 4
|
|
}
|
|
},
|
|
{
|
|
name: "SwiftKey",
|
|
ime: "com.touchtype.swiftkey/com.touchtype.KeyboardService",
|
|
pkg: "com.touchtype.swiftkey",
|
|
layout: {
|
|
start: h(1800),
|
|
end: h(2300),
|
|
keyHeight: h(100),
|
|
rowMargin: h(10),
|
|
keyWidth: w(100),
|
|
specialKeyWidth: w(100 + 50),
|
|
spaceBarWidth: w(100 * 4.5),
|
|
rows: 4
|
|
}
|
|
},
|
|
{
|
|
name: "Grammarly Keyboard",
|
|
ime: "com.grammarly.android.keyboard/.LatinIME",
|
|
pkg: "com.grammarly.android.keyboard",
|
|
layout: {
|
|
start: h(1700),
|
|
end: h(2300),
|
|
keyHeight: h(120),
|
|
rowMargin: h(25),
|
|
keyWidth: w(100),
|
|
specialKeyWidth: w(140),
|
|
spaceBarWidth: w(100 * 4),
|
|
rows: 4
|
|
}
|
|
}
|
|
];
|
|
|
|
export async function getKeyboards(device: AndroidDevice) {
|
|
const imeList = (await device.shell("ime list -s -a"))
|
|
.toString("utf-8")
|
|
.split("\n");
|
|
return SUPPORTED_KEYBOARDS.filter((keyboard) =>
|
|
imeList.includes(keyboard.ime)
|
|
);
|
|
}
|
|
|
|
export async function setKeyboard(device: AndroidDevice, ime: string) {
|
|
const output = (await device.shell(`ime set ${ime}`)).toString("utf-8");
|
|
return output.includes(`Input method ${ime} selected`);
|
|
}
|
|
|
|
export async function type(
|
|
page: Page,
|
|
device: AndroidDevice,
|
|
keyboard: Keyboard,
|
|
deviceSize: DeviceSize,
|
|
str: string
|
|
) {
|
|
for (const char of str) {
|
|
const specialKey = SPECIAL_KEY_MAP[char];
|
|
if (specialKey)
|
|
await device.input.tap(getSpecialKey(keyboard, deviceSize, specialKey));
|
|
else await device.input.tap(getKey(keyboard, deviceSize, char));
|
|
|
|
await page.waitForTimeout(50);
|
|
}
|
|
}
|
|
|
|
export function getKey(
|
|
keyboard: Keyboard,
|
|
deviceSize: DeviceSize,
|
|
key: string
|
|
) {
|
|
key = key.toUpperCase();
|
|
const rowIndex = KEYBOARD_ROWS.findIndex((r) => r.includes(key));
|
|
if (rowIndex < 0) throw new Error(`Key (${key}) not found in any row.`);
|
|
const keyIndex = KEYBOARD_ROWS[rowIndex].indexOf(key);
|
|
const specialKeysCount = KEYBOARD_ROWS[rowIndex].filter(
|
|
(k, i) => k.length > 1 && i <= keyIndex
|
|
).length;
|
|
const emptySpaceCount = KEYBOARD_ROWS[rowIndex].filter(
|
|
(k, i) => k.length < 1 && i <= keyIndex
|
|
).length;
|
|
|
|
const keyHeight = deviceSize.h(keyboard.layout.keyHeight);
|
|
const rowMargin = deviceSize.h(keyboard.layout.rowMargin);
|
|
const keyWidth = deviceSize.w(keyboard.layout.keyWidth);
|
|
const specialKeyWidth = deviceSize.w(keyboard.layout.specialKeyWidth);
|
|
const start = deviceSize.h(keyboard.layout.start);
|
|
|
|
const specialKeysX = specialKeysCount * specialKeyWidth;
|
|
const emptySpaceX = emptySpaceCount * (keyWidth / 2);
|
|
const keysX = (keyIndex + 1 - specialKeysCount - emptySpaceCount) * keyWidth;
|
|
|
|
const y = (rowIndex + 1) * (keyHeight + rowMargin) + start;
|
|
|
|
//console.log(key, keysX + specialKeysX + emptySpaceX, y);
|
|
|
|
return { y, x: keysX + specialKeysX + emptySpaceX };
|
|
}
|
|
|
|
export function getSpecialKey(
|
|
keyboard: Keyboard,
|
|
deviceSize: DeviceSize,
|
|
key: "Space" | "Enter" | "Period"
|
|
) {
|
|
const keyHeight = deviceSize.h(keyboard.layout.keyHeight);
|
|
const rowMargin = deviceSize.h(keyboard.layout.rowMargin);
|
|
const keyWidth = deviceSize.w(keyboard.layout.keyWidth);
|
|
const specialKeyWidth = deviceSize.w(keyboard.layout.specialKeyWidth);
|
|
const spaceBarWidth = deviceSize.w(keyboard.layout.spaceBarWidth);
|
|
const start = deviceSize.h(keyboard.layout.start);
|
|
|
|
return {
|
|
x:
|
|
key === "Space"
|
|
? specialKeyWidth + 2 * keyWidth + spaceBarWidth / 2
|
|
: key === "Period"
|
|
? specialKeyWidth + 3 * keyWidth + spaceBarWidth
|
|
: specialKeyWidth + 4 * keyWidth + spaceBarWidth,
|
|
y: keyboard.layout.rows * (keyHeight + rowMargin) + start
|
|
};
|
|
}
|