mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-25 16:09:42 +01:00
mobile: add support for color shortcuts on homescreen
This commit is contained in:
@@ -246,7 +246,7 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void addShortcut(final String id, final String type, final String title, final String description, Promise promise) {
|
||||
public void addShortcut(final String id, final String type, final String title, final String description, final String color, Promise promise) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
promise.reject("UNSUPPORTED", "Pinned launcher shortcuts require Android 8.0 or higher");
|
||||
return;
|
||||
@@ -263,7 +263,7 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, android.net.Uri.parse(uri));
|
||||
intent.setPackage(mContext.getPackageName());
|
||||
|
||||
Icon icon = createLetterIcon(type, title);
|
||||
Icon icon = createLetterIcon(type, title, color);
|
||||
ShortcutInfo shortcut = new ShortcutInfo.Builder(mContext, id)
|
||||
.setShortLabel(title)
|
||||
.setLongLabel(description != null && !description.isEmpty() ? description : title)
|
||||
@@ -301,7 +301,7 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void updateShortcut(final String id, final String title, final String description, Promise promise) {
|
||||
public void updateShortcut(final String id, final String type, final String title, final String description,final String color, Promise promise) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
promise.reject("UNSUPPORTED", "Pinned launcher shortcuts require Android 8.0 or higher");
|
||||
return;
|
||||
@@ -327,9 +327,10 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
if (existingShortcut == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Icon icon = createLetterIcon(type, title, color);
|
||||
ShortcutInfo updatedShortcut = new ShortcutInfo.Builder(mContext, id)
|
||||
.setShortLabel(title)
|
||||
.setIcon(icon)
|
||||
.setLongLabel(description != null && !description.isEmpty() ? description : title)
|
||||
.setIntent(existingShortcut.getIntent())
|
||||
.build();
|
||||
@@ -397,6 +398,8 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
data.putString("type", "notebook");
|
||||
} else if (info.getCategories().contains("tag")) {
|
||||
data.putString("type", "tag");
|
||||
} else if (info.getCategories().contains("color")) {
|
||||
data.putString("type", "color");
|
||||
}
|
||||
}
|
||||
shortcuts.pushMap(data);
|
||||
@@ -404,12 +407,12 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
promise.resolve(shortcuts);
|
||||
}
|
||||
|
||||
private Icon createLetterIcon(String type, String title) {
|
||||
private Icon createLetterIcon(String type, String title, String colorCode) {
|
||||
|
||||
String letter = type.contains("tag") ? "#" : title != null && !title.isEmpty()
|
||||
? title.substring(0, 1).toUpperCase()
|
||||
: "?";
|
||||
int color = getColorForLetter(letter);
|
||||
int color = type.equals("color") ? Color.parseColor(colorCode) : getColorForLetter(letter);
|
||||
|
||||
if (type.equals("notebook")) return Icon.createWithResource(mContext, R.drawable.ic_notebook);
|
||||
// Use a larger canvas and fill it completely to avoid white borders from launcher masking.
|
||||
@@ -417,19 +420,24 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
Bitmap bitmap = Bitmap.createBitmap(iconSize, iconSize, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
if (type.equals("color")) {
|
||||
Paint backgroundPaint = new Paint();
|
||||
backgroundPaint.setColor(color);
|
||||
backgroundPaint.setAntiAlias(true);
|
||||
canvas.drawCircle(iconSize / 2, iconSize / 2, iconSize/2, backgroundPaint);
|
||||
} else {
|
||||
Paint textPaint = new Paint();
|
||||
textPaint.setColor(color);
|
||||
textPaint.setTextSize(130);
|
||||
textPaint.setAntiAlias(true);
|
||||
textPaint.setTextAlign(Paint.Align.CENTER);
|
||||
textPaint.setTypeface(android.graphics.Typeface.create(android.graphics.Typeface.DEFAULT, android.graphics.Typeface.BOLD));
|
||||
|
||||
float x = iconSize / 2f;
|
||||
float y = (iconSize / 2f) - ((textPaint.descent() + textPaint.ascent()) / 2f);
|
||||
|
||||
Paint textPaint = new Paint();
|
||||
textPaint.setColor(color);
|
||||
textPaint.setTextSize(130);
|
||||
textPaint.setAntiAlias(true);
|
||||
textPaint.setTextAlign(Paint.Align.CENTER);
|
||||
textPaint.setTypeface(android.graphics.Typeface.create(android.graphics.Typeface.DEFAULT, android.graphics.Typeface.BOLD));
|
||||
|
||||
float x = iconSize / 2f;
|
||||
float y = (iconSize / 2f) - ((textPaint.descent() + textPaint.ascent()) / 2f);
|
||||
|
||||
canvas.drawText(letter, x, y, textPaint);
|
||||
canvas.drawText(letter, x, y, textPaint);
|
||||
}
|
||||
|
||||
return Icon.createWithBitmap(bitmap);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/* eslint-disable no-inner-declarations */
|
||||
import { useAreFeaturesAvailable } from "@notesnook/common";
|
||||
import {
|
||||
Color,
|
||||
createInternalLink,
|
||||
Item,
|
||||
ItemReference,
|
||||
@@ -1191,7 +1192,10 @@ export const useActions = ({
|
||||
|
||||
if (
|
||||
Platform.OS === "android" &&
|
||||
(item.type === "tag" || item.type === "note" || item.type === "notebook")
|
||||
(item.type === "tag" ||
|
||||
item.type === "note" ||
|
||||
item.type === "notebook" ||
|
||||
item.type === "color")
|
||||
) {
|
||||
actions.push({
|
||||
id: "launcher-shortcut",
|
||||
@@ -1203,7 +1207,8 @@ export const useActions = ({
|
||||
item.id,
|
||||
item.type,
|
||||
item.title,
|
||||
(item as Note).headline || (item as Notebook).description || ""
|
||||
(item as Note).headline || (item as Notebook).description || "",
|
||||
(item as Color).colorCode
|
||||
);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
@@ -216,6 +216,22 @@ const onAppOpenedFromURL = async (event: {
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
url.startsWith("https://app.notesnook.com/open_color?") &&
|
||||
!event.isInitialUrl
|
||||
) {
|
||||
const id = new URL(url).searchParams.get("id");
|
||||
if (id) {
|
||||
const color = await db.colors.color(id);
|
||||
if (color) {
|
||||
Navigation.navigate("ColoredNotes", {
|
||||
type: "color",
|
||||
id: color.id,
|
||||
item: color,
|
||||
canGoBack: true
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (url.startsWith("https://app.notesnook.com/open_reminder")) {
|
||||
const id = new URL(url).searchParams.get("id");
|
||||
if (id) {
|
||||
|
||||
@@ -87,6 +87,18 @@ const AppNavigation = React.memo(
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else if (url?.startsWith("https://app.notesnook.com/open_color?")) {
|
||||
const id = new URL(url).searchParams.get("id");
|
||||
if (id) {
|
||||
setHome({
|
||||
name: "ColoredNotes",
|
||||
params: {
|
||||
type: "color",
|
||||
id: id
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ async function syncShortcuts(result: ShortcutInfo[]) {
|
||||
} else if (note.title !== shortcut.title) {
|
||||
NotesnookModule.updateShortcut(
|
||||
shortcut.id,
|
||||
"note",
|
||||
note.title,
|
||||
note.headline
|
||||
);
|
||||
@@ -61,6 +62,7 @@ async function syncShortcuts(result: ShortcutInfo[]) {
|
||||
} else if (notebook.title !== shortcut.title) {
|
||||
NotesnookModule.updateShortcut(
|
||||
shortcut.id,
|
||||
"notebook",
|
||||
notebook.title,
|
||||
notebook.description
|
||||
);
|
||||
@@ -73,7 +75,28 @@ async function syncShortcuts(result: ShortcutInfo[]) {
|
||||
if (!tag) {
|
||||
NotesnookModule.removeShortcut(shortcut.id);
|
||||
} else if (tag.title !== shortcut.title) {
|
||||
NotesnookModule.updateShortcut(shortcut.id, tag.title, tag.title);
|
||||
NotesnookModule.updateShortcut(
|
||||
shortcut.id,
|
||||
"tag",
|
||||
tag.title,
|
||||
tag.title
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
{
|
||||
const color = await db.colors.color(shortcut.id);
|
||||
if (!color) {
|
||||
NotesnookModule.removeShortcut(shortcut.id);
|
||||
} else if (color.title !== shortcut.title) {
|
||||
NotesnookModule.updateShortcut(
|
||||
shortcut.id,
|
||||
"color",
|
||||
color.title,
|
||||
color.title,
|
||||
color.colorCode
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -23,7 +23,7 @@ export type ShortcutInfo = {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
type: "note" | "notebook" | "tag";
|
||||
type: "note" | "notebook" | "tag" | "color";
|
||||
};
|
||||
|
||||
interface NotesnookModuleInterface {
|
||||
@@ -50,15 +50,18 @@ interface NotesnookModuleInterface {
|
||||
isGestureNavigationEnabled: () => boolean;
|
||||
addShortcut: (
|
||||
id: string,
|
||||
type: "note" | "notebook" | "tag",
|
||||
type: "note" | "notebook" | "tag" | "color",
|
||||
title: string,
|
||||
description?: string
|
||||
description?: string,
|
||||
color?: string
|
||||
) => Promise<boolean>;
|
||||
removeShortcut: (id: string) => Promise<boolean>;
|
||||
updateShortcut: (
|
||||
id: string,
|
||||
type: "note" | "notebook" | "tag" | "color",
|
||||
title: string,
|
||||
description?: string
|
||||
description?: string,
|
||||
color?: string
|
||||
) => Promise<boolean>;
|
||||
removeAllShortcuts: () => Promise<boolean>;
|
||||
getAllShortcuts: () => Promise<ShortcutInfo[]>;
|
||||
|
||||
Reference in New Issue
Block a user