mirror of
https://github.com/ChronosX88/wind.git
synced 2024-12-04 18:12:18 +00:00
Implement new thread creation
This commit is contained in:
parent
cf15aae5ac
commit
1bcc2613b4
112
lib/create_thread_screen.dart
Normal file
112
lib/create_thread_screen.dart
Normal file
@ -0,0 +1,112 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wind/thread_list_model.dart';
|
||||
import 'package:wind/thread_model.dart';
|
||||
|
||||
class CreateThreadScreen extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() => _CreateThreadScreenState();
|
||||
}
|
||||
|
||||
class _CreateThreadScreenState extends State<CreateThreadScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text("Создать новый тред")),
|
||||
body: Center(
|
||||
child: Container(
|
||||
width: 640,
|
||||
child: Consumer<ThreadModel>(
|
||||
builder: (context, value, child) => CreateThreadForm(model: value),
|
||||
),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
class CreateThreadForm extends StatefulWidget {
|
||||
CreateThreadForm({Key? key, required this.model}) : super(key: key);
|
||||
|
||||
ThreadModel model;
|
||||
|
||||
@override
|
||||
CreateThreadFormState createState() {
|
||||
return CreateThreadFormState(model);
|
||||
}
|
||||
}
|
||||
|
||||
// Define a corresponding State class.
|
||||
// This class holds data related to the form.
|
||||
class CreateThreadFormState extends State<CreateThreadForm> {
|
||||
CreateThreadFormState(this.model);
|
||||
|
||||
ThreadModel model;
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
String _subject = "";
|
||||
String _text = "";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: TextFormField(
|
||||
onSaved: ((newValue) {
|
||||
_subject = newValue!;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(), labelText: "Название поста"),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Пожалуйста, введите название';
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: TextFormField(
|
||||
onSaved: (newValue) {
|
||||
_text = newValue!;
|
||||
},
|
||||
minLines: 5,
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: 35,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(), labelText: "Текст поста"),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Пожалуйста, введите текст';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
)),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
_formKey.currentState!.save();
|
||||
model.createThread(_subject, _text).then((value) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Тред создан!')),
|
||||
);
|
||||
Provider.of<ThreadListModel>(context, listen: false)
|
||||
.update();
|
||||
Navigator.pop(context);
|
||||
}, onError: (error) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'При создании треда произошла ошибка: ${error.toString()}')),
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Text("Создать"))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
125
lib/main.dart
125
lib/main.dart
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wind/create_thread_screen.dart';
|
||||
import 'package:wind/newsgroup_list_view.dart';
|
||||
import 'package:wind/nntp_client.dart';
|
||||
import 'package:wind/thread_list_view.dart';
|
||||
@ -47,6 +48,9 @@ class MyApp extends StatelessWidget {
|
||||
threadNumber:
|
||||
int.parse(uriData.queryParametersAll['num']!.first));
|
||||
break;
|
||||
case '/thread/create':
|
||||
pageView = CreateThreadScreen();
|
||||
break;
|
||||
default:
|
||||
pageView = MyHomePage(title: 'Wind');
|
||||
break;
|
||||
@ -82,64 +86,69 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// This method is rerun every time setState is called, for instance as done
|
||||
// by the _incrementCounter method above.
|
||||
//
|
||||
// The Flutter framework has been optimized to make rerunning build methods
|
||||
// fast, so that you can just rebuild anything that needs updating rather
|
||||
// than having to individually change instances of widgets.
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
// Here we take the value from the MyHomePage object that was created by
|
||||
// the App.build method, and use it to set our appbar title.
|
||||
title: Text(widget.title),
|
||||
actions: [
|
||||
TextButton.icon(
|
||||
onPressed: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Обновление списка тредов...')),
|
||||
);
|
||||
Provider.of<ThreadListModel>(context, listen: false).update();
|
||||
},
|
||||
label: const Text("Обновить"),
|
||||
style: TextButton.styleFrom(
|
||||
primary: Theme.of(context).colorScheme.onPrimary),
|
||||
icon: Icon(Icons.sync))
|
||||
],
|
||||
),
|
||||
body: Center(
|
||||
child: Container(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.all(16),
|
||||
child: Text(
|
||||
"Новостные группы",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold, fontSize: 20),
|
||||
)),
|
||||
Expanded(
|
||||
child: Builder(
|
||||
builder: (context) =>
|
||||
NewsgroupListView(client: nntpClient))),
|
||||
],
|
||||
),
|
||||
),
|
||||
const VerticalDivider(thickness: 1, width: 1),
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Consumer<ThreadListModel>(
|
||||
builder: ((context, value, child) => ThreadListView())),
|
||||
))
|
||||
],
|
||||
),
|
||||
return Consumer<ThreadListModel>(
|
||||
builder: (context, value, child) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.title),
|
||||
actions: value.currentGroup != ""
|
||||
? [
|
||||
TextButton.icon(
|
||||
onPressed: () =>
|
||||
Navigator.pushNamed(context, "/thread/create"),
|
||||
icon: Icon(Icons.add),
|
||||
label: Text("Создать тред"),
|
||||
style: TextButton.styleFrom(
|
||||
primary: Theme.of(context).colorScheme.onPrimary),
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Обновление списка тредов...')),
|
||||
);
|
||||
Provider.of<ThreadListModel>(context, listen: false)
|
||||
.update();
|
||||
},
|
||||
label: const Text("Обновить"),
|
||||
style: TextButton.styleFrom(
|
||||
primary: Theme.of(context).colorScheme.onPrimary),
|
||||
icon: Icon(Icons.sync))
|
||||
]
|
||||
: [],
|
||||
),
|
||||
));
|
||||
body: Center(
|
||||
child: Container(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.all(16),
|
||||
child: Text(
|
||||
"Новостные группы",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold, fontSize: 20),
|
||||
)),
|
||||
Expanded(
|
||||
child: Builder(
|
||||
builder: (context) =>
|
||||
NewsgroupListView(client: nntpClient))),
|
||||
],
|
||||
),
|
||||
),
|
||||
const VerticalDivider(thickness: 1, width: 1),
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Consumer<ThreadListModel>(
|
||||
builder: ((context, value, child) => ThreadListView())),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class MessageItemView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: this.isOpPost
|
||||
padding: this.isOpPost
|
||||
? EdgeInsets.only(bottom: 10, left: 10, right: 10, top: 16)
|
||||
: isLast
|
||||
? EdgeInsets.only(left: 10, right: 10, bottom: 16)
|
||||
|
@ -40,7 +40,7 @@ class ThreadListModel extends ChangeNotifier {
|
||||
_curItems.add(ThreadItem(
|
||||
msg.getHeaderValue("Message-Id")!,
|
||||
number,
|
||||
msg.getHeaderValue("Subject")!,
|
||||
msg.decodeSubject()!,
|
||||
msg.getHeaderValue("From")!,
|
||||
msg.getHeaderValue("Date")!,
|
||||
msg.decodeTextPlainPart()!));
|
||||
|
@ -13,7 +13,7 @@ class ThreadModel extends ChangeNotifier {
|
||||
var mi = MessageItem(
|
||||
msg.getHeaderValue("Message-Id")!,
|
||||
number,
|
||||
msg.getHeaderValue("Subject")!,
|
||||
msg.decodeSubject()!,
|
||||
msg.getHeaderValue("From")!,
|
||||
msg.getHeaderValue("Date")!,
|
||||
msg.decodeTextPlainPart()!);
|
||||
@ -37,7 +37,7 @@ class ThreadModel extends ChangeNotifier {
|
||||
null,
|
||||
message.getHeaderValue("From")!,
|
||||
message.getHeaderValue("Date")!,
|
||||
message.decodeTextPlainPart()!));
|
||||
message.decodeTextPlainPart()!.trim()));
|
||||
});
|
||||
|
||||
return items;
|
||||
@ -45,7 +45,7 @@ class ThreadModel extends ChangeNotifier {
|
||||
|
||||
Future<int> postMessage(MimeMessage opPost, String text) async {
|
||||
var msg = MessageBuilder.buildSimpleTextMessage(
|
||||
MailAddress.empty(), [], text,
|
||||
MailAddress.empty(), [], text.trim(),
|
||||
subject: "Re: " + opPost.decodeSubject()!);
|
||||
msg.setHeader("From", "anonymous");
|
||||
msg.addHeader("In-Reply-To", opPost.getHeaderValue("Message-Id"));
|
||||
@ -54,6 +54,15 @@ class ThreadModel extends ChangeNotifier {
|
||||
return await client!.postArticle(msg);
|
||||
}
|
||||
|
||||
Future<int> createThread(String subject, String text) async {
|
||||
var msg = MessageBuilder.buildSimpleTextMessage(
|
||||
MailAddress.empty(), [], text.trim(),
|
||||
subject: subject);
|
||||
msg.setHeader("From", "anonymous");
|
||||
msg.addHeader("Newsgroups", client!.currentGroup!);
|
||||
return await client!.postArticle(msg);
|
||||
}
|
||||
|
||||
void update() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user