added prj editing page, must change to dialog bcz page too big
All checks were successful
Build CI / AMD64 Build (push) Successful in 3m23s
Build CI / ARM64 Build (push) Successful in 7m16s

This commit is contained in:
2026-02-15 19:06:08 +05:30
parent 985d7e5e21
commit ec3e69ffa9
8 changed files with 203 additions and 32 deletions

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import "package:prod/views/editors.dart"; import "package:prod/views/editors.dart";
import "package:prod/views/home.dart"; import "package:prod/views/home.dart";
import "package:prod/views/managePrj.dart";
import "package:yaru/yaru.dart"; import "package:yaru/yaru.dart";
import "package:provider/provider.dart"; import "package:provider/provider.dart";
import "package:prod/models/globalModel.dart"; import "package:prod/models/globalModel.dart";
@@ -27,6 +28,7 @@ class MyApp extends StatelessWidget {
routes: { routes: {
"/": (context) => HomePage(), "/": (context) => HomePage(),
"/editors": (context) => EditorEditor(), "/editors": (context) => EditorEditor(),
"/manageprj": (context) => ManageProject(),
}, },
initialRoute: "/", initialRoute: "/",
); );

View File

@@ -8,7 +8,6 @@ class Editor {
final String name; final String name;
final String command; final String command;
final String commandTemplate; final String commandTemplate;
// final Icon icon;
const Editor( const Editor(
this.sname, this.sname,
@@ -39,6 +38,7 @@ class Editor {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
"sname": sname,
"name": name, "name": name,
"command": command, "command": command,
"commandTemplate": commandTemplate, "commandTemplate": commandTemplate,
@@ -50,7 +50,8 @@ class Editor {
if (!data.containsKey("name") || if (!data.containsKey("name") ||
!data.containsKey("command") || !data.containsKey("command") ||
!data.containsKey("commandTemplate") || !data.containsKey("commandTemplate") ||
!data.containsKey("id")) { !data.containsKey("id") ||
!data.containsKey("sname")) {
print("Found invalid editor config when parsing: $data"); print("Found invalid editor config when parsing: $data");
return Editor("!!", "null", "null", "null", "null"); return Editor("!!", "null", "null", "null", "null");
} }

View File

@@ -12,11 +12,24 @@ class GlobalModel extends ChangeNotifier {
late List<Editor> editors; late List<Editor> editors;
late SharedPreferences prefs; late SharedPreferences prefs;
bool importedData = false; bool importedData = false;
bool edited = false;
GlobalModel() { GlobalModel() {
SharedPreferences.getInstance().then((a) { SharedPreferences.getInstance().then((a) {
print("Loaded sp"); print("Loaded sp");
prefs = a; prefs = a;
if (prefs.containsKey(kEditorsKey)) {
String edtData = prefs.getString(kEditorsKey)!;
List<dynamic> data = jsonDecode(edtData);
editors = [];
for (var d in data) {
editors.add(Editor.fromJson(d));
}
} else {
editors = [];
prefs.setString(kEditorsKey, jsonEncode(editors));
}
if (prefs.containsKey(kProjectsKey)) { if (prefs.containsKey(kProjectsKey)) {
String prjData = prefs.getString(kProjectsKey)!; String prjData = prefs.getString(kProjectsKey)!;
List<dynamic> data = jsonDecode(prjData); List<dynamic> data = jsonDecode(prjData);
@@ -30,18 +43,6 @@ class GlobalModel extends ChangeNotifier {
} }
print(projects); print(projects);
if (prefs.containsKey(kEditorsKey)) {
String edtData = prefs.getString(kEditorsKey)!;
List<dynamic> data = jsonDecode(edtData);
editors = [];
for (var d in data) {
editors.add(Editor.fromJson(d));
}
} else {
editors = [];
prefs.setString(kEditorsKey, jsonEncode(editors));
}
hoverShow = List.filled(projects.length, false, growable: true); hoverShow = List.filled(projects.length, false, growable: true);
print("loaded data"); print("loaded data");
importedData = true; importedData = true;
@@ -94,6 +95,11 @@ class GlobalModel extends ChangeNotifier {
return hoverShow[index]; return hoverShow[index];
} }
void updatePrj(int index, Project prj) {
projects[index] = prj;
notifyListeners();
}
// Editor List Management. // Editor List Management.
void addEdt(Editor edt) { void addEdt(Editor edt) {
@@ -115,4 +121,15 @@ class GlobalModel extends ChangeNotifier {
Editor nthEdt(int index) { Editor nthEdt(int index) {
return editors[index]; return editors[index];
} }
// Editing controller
bool get isEdited {
return edited;
}
void updateEdited(bool a) {
edited = a;
notifyListeners();
}
} }

View File

@@ -21,7 +21,7 @@ class HomePage extends StatelessWidget {
body: Padding( body: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: !gm.importedData child: !gm.importedData
? Container() ? YaruLinearProgressIndicator()
: gm.lenPrj > 0 : gm.lenPrj > 0
? LayoutBuilder( ? LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {

141
lib/views/managePrj.dart Normal file
View File

@@ -0,0 +1,141 @@
import "dart:io";
import "package:flutter/material.dart";
import "package:prod/models/globalModel.dart";
import "package:prod/models/project.dart";
import "package:provider/provider.dart";
class ManageProject extends StatelessWidget {
const ManageProject({super.key});
@override
Widget build(BuildContext context) {
final id = ModalRoute.of(context)?.settings.arguments as int;
GlobalModel gm = Provider.of(context);
final Project prj = gm.nthPrj(id);
TextEditingController nameController = TextEditingController();
TextEditingController pathController = TextEditingController();
TextEditingController langController = TextEditingController();
nameController.text = prj.name;
pathController.text = prj.path.path;
langController.text = prj.language;
return Scaffold(
appBar: AppBar(title: Text("/ PROject Dashboard / Editing ${prj.name} ")),
body: Container(
// constraints: BoxConstraints(maxWidth: 500),
child: CustomScrollView(
slivers: [
SliverAppBar(
// title: gm.isEdited ? Text("Unsaved Changes") : null,
pinned: false,
snap: false,
floating: false,
automaticallyImplyLeading: false,
automaticallyImplyActions: false,
backgroundColor: Colors.transparent,
shape: LinearBorder(),
),
SliverToBoxAdapter(
child: TextField(
style: TextStyle(fontSize: 50),
controller: nameController,
textAlign: .center,
// onEditingComplete: () => gm.updateEdited(true),
decoration: InputDecoration(
border: .none,
enabledBorder: .none,
fillColor: Colors.transparent,
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
style: TextStyle(fontSize: 30),
controller: pathController,
textAlign: .center,
// onEditingComplete: () => gm.updateEdited(true),
decoration: InputDecoration(
border: .none,
// enabledBorder: .none,
fillColor: Colors.transparent,
),
),
),
),
SliverToBoxAdapter(
child: TextField(
style: TextStyle(fontSize: 30),
controller: langController,
textAlign: .center,
// onEditingComplete: () => gm.updateEdited(true),
decoration: InputDecoration(
border: .none,
enabledBorder: .none,
fillColor: Colors.transparent,
),
),
),
SliverList.list(
children: [
Row(
children: [
OutlinedButton(
child: Text("Delete"),
onPressed: () {
Navigator.pop(context);
gm.delPrj(id);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Deleted ${prj.name}"),
duration: Duration(milliseconds: 2350),
),
);
},
),
OutlinedButton(
child: Text("Cancel"),
onPressed: () => Navigator.pop(context),
),
OutlinedButton(
child: Text("Save"),
onPressed: () {
gm.updatePrj(
id,
Project(
nameController.text,
langController.text,
File(pathController.text),
prj.editors,
prj.isGit,
prj.enableTerminal,
),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Updated Project Details"),
duration: Duration(milliseconds: 2500),
),
);
},
// gm.updateEdited(false);
),
],
),
],
),
// SliverList.builder(
// itemCount: 3,
// itemBuilder: (context, index) {
// return Placeholder();
// },
// ),
],
),
),
);
}
}

View File

@@ -14,8 +14,6 @@ class EditorCard extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
GlobalModel gm = Provider.of<GlobalModel>(context); GlobalModel gm = Provider.of<GlobalModel>(context);
final Editor edt = gm.nthEdt(id); final Editor edt = gm.nthEdt(id);
final String icon =
"${edt.name.substring(0, 1).toUpperCase()}${edt.name.substring(1, 2).toLowerCase()}";
return YaruBanner( return YaruBanner(
padding: .only( padding: .only(
left: kYaruPagePadding, left: kYaruPagePadding,
@@ -28,7 +26,7 @@ class EditorCard extends StatelessWidget {
child: Row( child: Row(
children: [ children: [
Text("$icon", style: TextStyle(fontSize: 50)), Text("${edt.sname}", style: TextStyle(fontSize: 50)),
VerticalDivider(width: 20, thickness: 2), VerticalDivider(width: 20, thickness: 2),
Flexible( Flexible(
child: Column( child: Column(

View File

@@ -10,6 +10,7 @@ class ProjFAB extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
TextEditingController nameController = TextEditingController(); TextEditingController nameController = TextEditingController();
TextEditingController locationController = TextEditingController(); TextEditingController locationController = TextEditingController();
TextEditingController languageController = TextEditingController();
return FloatingActionButton( return FloatingActionButton(
onPressed: () { onPressed: () {
showDialog( showDialog(
@@ -33,6 +34,13 @@ class ProjFAB extends StatelessWidget {
decoration: InputDecoration(labelText: "Path"), decoration: InputDecoration(labelText: "Path"),
), ),
), ),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: languageController,
decoration: InputDecoration(labelText: "Language"),
),
),
Row( Row(
mainAxisAlignment: .end, mainAxisAlignment: .end,
@@ -47,7 +55,7 @@ class ProjFAB extends StatelessWidget {
Provider.of<GlobalModel>(context, listen: false).addPrj( Provider.of<GlobalModel>(context, listen: false).addPrj(
Project.newValidated( Project.newValidated(
nameController.text, nameController.text,
"Rust", languageController.text,
locationController.text, locationController.text,
[], [],
true, true,

View File

@@ -23,10 +23,14 @@ class ProjectCard extends StatelessWidget {
), ),
onHover: (st) => gm.setHoverShow(id, st), onHover: (st) => gm.setHoverShow(id, st),
onTap: () { onTap: () {
var shell = Shell(); // var shell = Shell();
Editor edt1 = gm.editors[0]; // Editor edt1 = gm.editors[0];
String comm = edt1.commandTemplate.replaceAll("\$path", prj.path.path); // String comm = edt1.commandTemplate.replaceAll("\$path", prj.path.path);
shell.run(comm); // shell.run(comm);
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text("Launched "), duration: Duration(seconds: 3)),
// );
Navigator.pushNamed(context, "/manageprj", arguments: id);
}, },
child: Center( child: Center(
child: Column( child: Column(
@@ -46,15 +50,15 @@ class ProjectCard extends StatelessWidget {
], ],
), ),
gm.getHoverShow(id) ? Text("${prj.path.path}") : Container(), gm.getHoverShow(id) ? Text("${prj.path.path}") : Container(),
gm.getHoverShow(id) // gm.getHoverShow(id)
? IconButton( // ? IconButton(
icon: Icon(Icons.close), // icon: Icon(Icons.close),
onPressed: () => gm.delPrj(id), // onPressed: () => gm.delPrj(id),
style: IconButton.styleFrom( // style: IconButton.styleFrom(
overlayColor: Color(0xffff0000), // overlayColor: Color(0xffff0000),
), // ),
) // )
: Container(), // : Container(),
], ],
), ),
), ),