about text

This commit is contained in:
randogoth 2025-02-24 15:44:25 +02:00
parent 8c602894a6
commit 2fde531964
11 changed files with 422 additions and 2 deletions

72
lib/codefield.dart Normal file
View file

@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:flutter_code_editor/flutter_code_editor.dart';
class WrappedCodeField extends StatefulWidget {
final CodeController controller;
final bool expands;
final bool wrap;
final TextStyle? textStyle;
final Color? cursorColor;
final EdgeInsets padding;
final bool readOnly;
final FocusNode? focusNode;
const WrappedCodeField({
super.key,
required this.controller,
this.expands = false,
this.wrap = true, // Enable wrapping by default
this.textStyle,
this.cursorColor,
this.padding = EdgeInsets.zero,
this.readOnly = false,
this.focusNode,
});
@override
_WrappedCodeFieldState createState() => _WrappedCodeFieldState();
}
class _WrappedCodeFieldState extends State<WrappedCodeField> {
late FocusNode _focusNode;
@override
void initState() {
super.initState();
_focusNode = widget.focusNode ?? FocusNode();
_focusNode.attach(context, onKeyEvent: _onKeyEvent);
}
KeyEventResult _onKeyEvent(FocusNode node, KeyEvent event) {
return widget.controller.onKey(event);
}
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
padding: widget.padding,
child: TextField(
focusNode: _focusNode,
controller: widget.controller,
expands: widget.expands,
minLines: widget.expands ? null : 1,
maxLines: widget.expands ? null : null, // Allows text to grow dynamically
scrollPhysics: widget.wrap ? const NeverScrollableScrollPhysics() : null,
style: widget.textStyle ?? const TextStyle(fontSize: 16),
cursorColor: widget.cursorColor ?? Colors.white,
decoration: const InputDecoration(
isCollapsed: true,
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16),
),
readOnly: widget.readOnly,
),
);
}
}

View file

@ -5,6 +5,7 @@ import 'package:device_apps/device_apps.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:plasmoid/read_only.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'day.dart'; import 'day.dart';
import 'night.dart'; import 'night.dart';
@ -356,6 +357,19 @@ class _AppLauncherScreenState extends State<AppLauncherScreen> {
return iconWidget; return iconWidget;
} }
_showInfoPage(BuildContext context, String title, String content) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ReadOnlyPage(
title: title,
content: content,
isDarkMode: widget.settings.darkTheme,
),
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -383,7 +397,7 @@ class _AppLauncherScreenState extends State<AppLauncherScreen> {
icon: SvgPicture.asset( icon: SvgPicture.asset(
"assets/plasmoid.svg", "assets/plasmoid.svg",
width: 30, width: 30,
color: Colors.orange, color: Color(0xff38818a),
), ),
onSelected: (String value) { onSelected: (String value) {
switch (value) { switch (value) {
@ -448,6 +462,9 @@ class _AppLauncherScreenState extends State<AppLauncherScreen> {
autoFocus: !widget.settings.autoFocus, autoFocus: !widget.settings.autoFocus,
)); ));
break; break;
case 'About':
_showInfoPage(context, "About", aboutContent);
break;
} }
}, },
itemBuilder: (BuildContext context) => [ itemBuilder: (BuildContext context) => [
@ -511,6 +528,13 @@ class _AppLauncherScreenState extends State<AppLauncherScreen> {
title: Text(widget.settings.autoFocus ? 'Disable Auto Focus' : 'Enable Auto Focus'), title: Text(widget.settings.autoFocus ? 'Disable Auto Focus' : 'Enable Auto Focus'),
), ),
), ),
PopupMenuItem<String>(
value: 'About',
child: ListTile(
leading: Icon(Icons.info_outline),
title: Text('About'),
),
),
], ],
), ),
), ),
@ -560,3 +584,28 @@ class _AppLauncherScreenState extends State<AppLauncherScreen> {
); );
} }
} }
String aboutContent = """
**Plasmoid** is a minimalist and opinionated app launcher for Android.
## Search & Launch:
Open Plasmoid and start typing in the search bar to filter your apps and shared files by name or tag.
Tap an app to launch it immediately.
## Tagging:
Swipe right on any item to edit its tags. For shared files, a tag dialog appears immediately upon sharing.
Tags help you organize items and are searchable using prefixes like @context, #general, or +project.
## Gestures & Settings:
Swipe left on an app to view its settings.
Use the menu button (plasmoid) to toggle settings such as icon visibility, color mode, theme, sorting (alphabetically or by last used), and auto-focus.
---
Made with 💚 by randogothimport 'package:plasmoid/texts.dart';
Icon by [Game Icons.net](https://game-icons.net/).
""";

81
lib/markdown.dart Normal file
View file

@ -0,0 +1,81 @@
import 'package:highlight/highlight.dart';
final markdown = Mode(refs: {}, aliases: [
"md",
"mkdown",
"mkd"
], contains: [
Mode(className: "section", variants: [
Mode(begin: "^#\\s{1,6}", end: "\$"),
Mode(begin: "^.+?\\n[=-]{2,}\$")
]),
Mode(begin: "<", end: ">", subLanguage: ["xml"], relevance: 0),
Mode(className: "bullet", begin: "^\\s*([*+-]|(\\d+\\.))\\s+"),
Mode(className: "strong", begin: "[*_]{2}.+?[*_]{2}"),
Mode(
className: "emphasis",
variants: [Mode(begin: "\\*.+?\\*"), Mode(begin: "_.+?_", relevance: 0)]),
Mode(className: "quote", begin: "^>\\s+", end: "\$"),
Mode(className: "code", variants: [
Mode(begin: "^```\\w*\\s*\$", end: "^```[ ]*\$"),
Mode(begin: "`.+?`"),
Mode(begin: "^( {4}|\\t)", end: "\$", relevance: 0)
]),
Mode(begin: "^[-\\*]{3,}", end: "\$"),
Mode(
begin: "\\[.+?\\][\\(\\[].*?[\\)\\]]",
returnBegin: true,
contains: [
Mode(
className: "string",
begin: "\\[",
end: "\\]",
excludeBegin: true,
returnEnd: true,
relevance: 0),
Mode(
className: "link",
begin: "\\]\\(",
end: "\\)",
excludeBegin: true,
excludeEnd: true),
Mode(
className: "symbol",
begin: "\\]\\[",
end: "\\]",
excludeBegin: true,
excludeEnd: true)
],
relevance: 10),
Mode(begin: "^\\[[^\\n]+\\]:", returnBegin: true, contains: [
Mode(
className: "symbol",
begin: "\\[",
end: "\\]",
excludeBegin: true,
excludeEnd: true),
Mode(className: "link", begin: ":\\s*", end: "\$", excludeBegin: true)
]),
// Custom Tag Highlighting
Mode(
className: "tag-hash",
begin: "(?<=\\s|^)#[a-zA-Z0-9_]+",
relevance: 10), // Magenta
Mode(
className: "tag-plus",
begin: "(?<=\\s|^)\\+[a-zA-Z0-9_]+",
relevance: 10), // Cyan
Mode(
className: "tag-at",
begin: "(?<=\\s|^)@[a-zA-Z0-9_]+",
relevance: 10), // Yellow
Mode(
className: "keyword",
begin: "(?<=\\s|^):[a-zA-Z0-9_]+",
relevance: 10),
Mode(
className: "variable",
begin: "(?<=\\s|^)\/[a-zA-Z0-9_\/]+",
relevance: 10), // Yellow
]);

54
lib/read_only.dart Normal file
View file

@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:flutter_code_editor/flutter_code_editor.dart';
import 'markdown.dart';
import 'day.dart';
import 'night.dart';
import 'codefield.dart'; // Ensure this includes WrappedCodeField
class ReadOnlyPage extends StatelessWidget {
final String title;
final String content;
final bool isDarkMode;
ReadOnlyPage({
required this.title,
required this.content,
required this.isDarkMode,
});
@override
Widget build(BuildContext context) {
final theme = isDarkMode ? nightTheme : dayTheme;
return Scaffold(
appBar: AppBar(title: Text(title)),
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Image.asset(
'assets/plasmoid_fg.png',
width: 200,
),
),
SizedBox(height: 20),
CodeTheme(
data: CodeThemeData(styles: theme),
child: WrappedCodeField(
controller: CodeController(
text: content,
language: markdown,
),
wrap: true,
readOnly: true,
),
),
SizedBox(height: 80)
],
)
),
);
}
}

View file

@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
} }

View file

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST

View file

@ -7,8 +7,10 @@ import Foundation
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }

View file

@ -25,6 +25,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.0" version: "2.11.0"
autotrie:
dependency: transitive
description:
name: autotrie
sha256: "55da6faefb53cfcb0abb2f2ca8636123fb40e35286bb57440d2cf467568188f8"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -41,6 +49,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
charcode:
dependency: transitive
description:
name: charcode
sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
url: "https://pub.dev"
source: hosted
version: "1.4.0"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@ -97,6 +113,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.2.0"
equatable:
dependency: transitive
description:
name: equatable
sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7"
url: "https://pub.dev"
source: hosted
version: "2.0.7"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -126,6 +150,22 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_code_editor:
dependency: "direct main"
description:
name: flutter_code_editor
sha256: "505ad56dcc8a7be4b782c8113574571bc4b9723499b0c1f385b3e2c3fae11f5d"
url: "https://pub.dev"
source: hosted
version: "0.3.2"
flutter_highlight:
dependency: transitive
description:
name: flutter_highlight
sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
flutter_launcher_icons: flutter_launcher_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -168,6 +208,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.1" version: "6.2.1"
highlight:
dependency: transitive
description:
name: highlight
sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
hive:
dependency: transitive
description:
name: hive
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
http: http:
dependency: transitive dependency: transitive
description: description:
@ -224,6 +280,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.1"
linked_scroll_controller:
dependency: transitive
description:
name: linked_scroll_controller
sha256: e6020062bcf4ffc907ee7fd090fa971e65d8dfaac3c62baf601a3ced0b37986a
url: "https://pub.dev"
source: hosted
version: "0.2.0"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -256,6 +320,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.15.0" version: "1.15.0"
mocktail:
dependency: transitive
description:
name: mocktail
sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -352,6 +424,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.1" version: "6.0.1"
scrollable_positioned_list:
dependency: transitive
description:
name: scrollable_positioned_list
sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287"
url: "https://pub.dev"
source: hosted
version: "0.3.8"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -461,6 +541,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.3" version: "0.7.3"
tuple:
dependency: transitive
description:
name: tuple
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.2"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -469,6 +557,70 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.4.0"
url_launcher:
dependency: transitive
description:
name: url_launcher
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
url: "https://pub.dev"
source: hosted
version: "6.3.14"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626"
url: "https://pub.dev"
source: hosted
version: "6.3.2"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
url: "https://pub.dev"
source: hosted
version: "3.2.2"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
vector_graphics: vector_graphics:
dependency: transitive dependency: transitive
description: description:
@ -543,4 +695,4 @@ packages:
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.6.0 <4.0.0" dart: ">=3.6.0 <4.0.0"
flutter: ">=3.24.0" flutter: ">=3.27.0"

View file

@ -16,6 +16,7 @@ dependencies:
flutter_svg: ^2.0.17 flutter_svg: ^2.0.17
google_fonts: ^6.2.1 google_fonts: ^6.2.1
flutter_launcher_icons: ^0.14.3 flutter_launcher_icons: ^0.14.3
flutter_code_editor: ^0.3.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View file

@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View file

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST