This commit is contained in:
Lorens Osman 2025-03-24 08:57:15 +03:00
commit 986096eb3a
19 changed files with 2800 additions and 0 deletions

10
.editorconfig Normal file
View file

@ -0,0 +1,10 @@
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_size = 4
tab_width = 4

3
.eslintignore Normal file
View file

@ -0,0 +1,3 @@
node_modules/
main.js

23
.eslintrc Normal file
View file

@ -0,0 +1,23 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"env": { "node": true },
"plugins": [
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
"@typescript-eslint/ban-ts-comment": "off",
"no-prototype-builtins": "off",
"@typescript-eslint/no-empty-function": "off"
}
}

22
.gitignore vendored Normal file
View file

@ -0,0 +1,22 @@
# vscode
.vscode
# Intellij
*.iml
.idea
# npm
node_modules
# Don't include the compiled main.js file in the repo.
# They should be uploaded to GitHub releases instead.
main.js
# Exclude sourcemaps
*.map
# obsidian
data.json
# Exclude macOS Finder (System Explorer) View States
.DS_Store

1
.npmrc Normal file
View file

@ -0,0 +1 @@
tag-version-prefix=""

5
LICENSE Normal file
View file

@ -0,0 +1,5 @@
Copyright (C) 2020-2025 by Dynalist Inc.
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

29
README.md Normal file
View file

@ -0,0 +1,29 @@
# Double row toolbar
Adds a second row to the Obsidian toolbar on mobile devices, allowing for more quick access buttons.
<details>
<summary>What the plugin do screenshot.</summary>
</br>
<p align="center"> <img src="./pics/Group.png" style="width: 350px !important;"></p>
</details>
<details>
<summary>Recommended Toolbar.</summary>
</br>
<p align="center"> <img src="./pics/Reccomended Toolbar.png" style="width: 550px !important;"></p>
</details>
<details>
<summary>How to add delete current line button.</summary>
<ol>
<li> Open a note and tap inside the editing area to show the toolbar.
<li> Tap the `configure mobile toolbar` button.
<li> Find `Double row toolbar : Delete current line` and add it to `Manage toolbar options`.
<li> If you can't find it, scroll to the bottom. In the `Add global command` section, search for `Double row toolbar : Delete current line`.
</ol>
</details>
---
<a href="https://www.buymeacoffee.com/lorens" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>

129
bump.ts Normal file
View file

@ -0,0 +1,129 @@
import { readFile, writeFile } from "fs/promises"; // Use promises version of fs methods
import { execSync } from "child_process";
import chalk from "chalk"; //chalk commonJs
import type { ForegroundColorName, BackgroundColorName } from "chalk";
type Msg = [string, ForegroundColorName | "white", BackgroundColorName | null];
// Define the package semver and app version
const packageSemver = "1.0.1"; // Replace with your desired package semver
const appVersion = "1.8.4"; // Replace with your desired app version
// Paths to the JSON files
const versionsFilePath = "./versions.json";
const manifestFilePath = "./manifest.json";
const packageFilePath = "./package.json";
// Function to update versions.json
async function updateVersionsFile() {
try {
const data = await readFile(versionsFilePath, "utf8");
const versions = JSON.parse(data);
versions[packageSemver] = appVersion;
const updatedJson = JSON.stringify(versions, null, "\t");
await writeFile(versionsFilePath, updatedJson, "utf8");
console.log(
logInsert([
`>> added "${packageSemver}: ${appVersion}" to versions.json. ✓✓`,
"blue",
null,
]),
);
} catch (err) {
console.error("Error updating versions.json:", err);
}
}
// Function to update manifest.json
async function updateManifestFile() {
try {
const data = await readFile(manifestFilePath, "utf8");
const manifest = JSON.parse(data);
manifest.version = packageSemver; // Update the version field
manifest.minAppVersion = appVersion; // Update the minAppVersion field
const updatedJson = JSON.stringify(manifest, null, "\t");
await writeFile(manifestFilePath, updatedJson, "utf8");
console.log(
logInsert([
`>> updated manifest.json: version="${packageSemver}", minAppVersion="${appVersion}". ✓✓`,
"blue",
null,
]),
);
} catch (err) {
console.error("Error updating manifest.json:", err);
}
}
// Function to update package.json
async function updatePackageJsonFile() {
try {
const data = await readFile(packageFilePath, "utf8");
const packageJson = JSON.parse(data);
packageJson.version = packageSemver; // Update the version field
const updatedJson = JSON.stringify(packageJson, null, "\t");
await writeFile(packageFilePath, updatedJson, "utf8");
console.log(
logInsert([
`>> updated package.json: version="${packageSemver}. ✓✓"`,
"blue",
null,
]),
);
} catch (err) {
console.error("Error updating package.json:", err);
}
}
// Function to perform Git operations
function gitCommitAndTag() {
try {
// Stage all changes
execSync("git add .");
console.log();
console.log(logInsert(["-- staged all changes. ✓✓", "greenBright", null]));
// Commit with the packageSemver as the message
execSync(`git commit -m "v${packageSemver}"`);
console.log(
logInsert([
`-- committed changes with message: "v${packageSemver}". ✓✓`,
"greenBright",
null,
]),
);
// Create a Git tag with the packageSemver
execSync(`git tag ${packageSemver}`);
console.log(
logInsert([
`-- created Git tag: ${packageSemver}. ✓✓`,
"greenBright",
null,
]),
);
console.log();
} catch (gitErr) {
console.error("Error during Git operations:", gitErr.message || gitErr);
}
}
export function logInsert(msgArr: Msg) {
const msg = {
msg: msgArr[0],
color: msgArr[1],
bgColor: msgArr[2],
};
if (msg.bgColor !== null) {
return chalk[msg.color][msg.bgColor](msg.msg);
}
return chalk[msg.color](msg.msg);
}
// Main function to run all steps in sequence
async function main() {
await updateVersionsFile();
await updateManifestFile();
await updatePackageJsonFile();
gitCommitAndTag(); // This will only run after all file updates are complete
}
// Run the main function
main();

49
esbuild.config.mjs Normal file
View file

@ -0,0 +1,49 @@
import esbuild from "esbuild";
import process from "process";
import builtins from "builtin-modules";
const banner =
`/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
`;
const prod = (process.argv[2] === "production");
const context = await esbuild.context({
banner: {
js: banner,
},
entryPoints: ["main.ts"],
bundle: true,
external: [
"obsidian",
"electron",
"@codemirror/autocomplete",
"@codemirror/collab",
"@codemirror/commands",
"@codemirror/language",
"@codemirror/lint",
"@codemirror/search",
"@codemirror/state",
"@codemirror/view",
"@lezer/common",
"@lezer/highlight",
"@lezer/lr",
...builtins],
format: "cjs",
target: "es2018",
logLevel: "info",
sourcemap: prod ? false : "inline",
treeShaking: true,
outfile: "main.js",
minify: prod,
});
if (prod) {
await context.rebuild();
process.exit(0);
} else {
await context.watch();
}

25
main.ts Normal file
View file

@ -0,0 +1,25 @@
import { Editor, MarkdownView, Plugin, Platform, Notice } from 'obsidian';
export default class DoubleRowToolbarPlugin extends Plugin {
async onload() {
if (Platform.isDesktop) {
new Notice("'Double row toolbar' plugin is not supported on desktop devices.");
return;
}
this.addCommand({
id: "delete-current-line",
name: "Delete current line",
icon: "scissors-line-dashed",
editorCallback: (editor: Editor, view: MarkdownView) => {
editor.exec("deleteLine");
editor.focus();
}
});
}
onunload() { }
}

11
manifest.json Normal file
View file

@ -0,0 +1,11 @@
{
"id": "double-row-toolbar",
"name": "Double row toolbar",
"version": "1.0.0",
"minAppVersion": "1.8.4",
"description": "Adds a second row to the Obsidian toolbar on mobile devices, allowing for more quick access buttons.",
"author": "Lorens Osman",
"authorUrl": "https://twitter.com/lorans_othman",
"fundingUrl": "https://www.buymeacoffee.com/lorens",
"isDesktopOnly": false
}

2411
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

26
package.json Normal file
View file

@ -0,0 +1,26 @@
{
"name": "double-row-toolbar",
"version": "1.0.0",
"description": "Adds a second row to the Obsidian toolbar on mobile devices, allowing for more quick access buttons.",
"main": "main.js",
"scripts": {
"dev": "node esbuild.config.mjs",
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"version": "node version-bump.mjs && git add manifest.json versions.json",
"bump": "tsx bump.ts"
},
"keywords": [],
"author": "",
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",
"@typescript-eslint/eslint-plugin": "5.29.0",
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"chalk": "^5.4.1",
"esbuild": "0.17.3",
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
}
}

BIN
pics/Group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

14
styles.css Normal file
View file

@ -0,0 +1,14 @@
.mobile-toolbar {
.mobile-toolbar-options-container {
height: 100%;
.mobile-toolbar-options-list {
padding-bottom: 2px;
padding-top: 2px;
display: grid !important;
grid-template-rows: 1fr 1fr;
grid-auto-flow: column;
row-gap: 4px;
}
}
}

24
tsconfig.json Normal file
View file

@ -0,0 +1,24 @@
{
"compilerOptions": {
"baseUrl": ".",
"inlineSourceMap": true,
"inlineSources": true,
"module": "ESNext",
"target": "ES6",
"allowJs": true,
"noImplicitAny": true,
"moduleResolution": "node",
"importHelpers": true,
"isolatedModules": true,
"strictNullChecks": true,
"lib": [
"DOM",
"ES5",
"ES6",
"ES7"
]
},
"include": [
"**/*.ts"
]
}

14
version-bump.mjs Normal file
View file

@ -0,0 +1,14 @@
import { readFileSync, writeFileSync } from "fs";
const targetVersion = process.env.npm_package_version;
// read minAppVersion from manifest.json and bump version to target version
let manifest = JSON.parse(readFileSync("manifest.json", "utf8"));
const { minAppVersion } = manifest;
manifest.version = targetVersion;
writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t"));
// update versions.json with target version and minAppVersion from manifest.json
let versions = JSON.parse(readFileSync("versions.json", "utf8"));
versions[targetVersion] = minAppVersion;
writeFileSync("versions.json", JSON.stringify(versions, null, "\t"));

4
versions.json Normal file
View file

@ -0,0 +1,4 @@
{
"1.0.0": "1.8.4",
"1.0.1": "1.8.4"
}