fit images correctly
This commit is contained in:
parent
d5675521f8
commit
e80623ccbf
|
@ -100,3 +100,13 @@ Future<String> loadToken() async {
|
|||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> saveBatchSize(int size) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return await prefs.setInt("post-batch-size", size);
|
||||
}
|
||||
|
||||
Future<int> loadBatchSize() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getInt("post-batch-size") ?? 5;
|
||||
}
|
||||
|
|
|
@ -95,12 +95,13 @@ class ThreadModel {
|
|||
}
|
||||
}
|
||||
|
||||
Future<ThreadModel> getTimelineFromServer(String? olderThan) async {
|
||||
Future<List<ThreadModel>> getTimelineFromServer(String? index) async {
|
||||
const limit = 5;
|
||||
final token = await settings.loadToken();
|
||||
|
||||
Map<String, String> query = {"limit": 1.toString()};
|
||||
if (olderThan != null) {
|
||||
query.addAll({"max_id": olderThan});
|
||||
Map<String, String> query = {"limit": limit.toString()};
|
||||
if (index != null) {
|
||||
query.addAll({"max_id": index});
|
||||
}
|
||||
|
||||
final baseUrl = await settings.loadInstanceUrl();
|
||||
|
@ -115,13 +116,16 @@ Future<ThreadModel> getTimelineFromServer(String? olderThan) async {
|
|||
headers.addAll(global.defaultHeaders);
|
||||
|
||||
http.Response response = await http.get(url, headers: headers);
|
||||
|
||||
while (response.statusCode != 200) {
|
||||
await Future.delayed(const Duration(seconds: 5));
|
||||
response = await http.get(url, headers: headers);
|
||||
}
|
||||
|
||||
final List<dynamic> json = await jsonDecode(response.body);
|
||||
final PostModel post = PostModel.fromJson(json[0]);
|
||||
|
||||
return await post.getThread();
|
||||
List<ThreadModel> threads = [];
|
||||
for (int i = 0; i < json.length; i++) {
|
||||
threads.add(await PostModel.fromJson(json[i]).getThread());
|
||||
}
|
||||
return threads;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import 'package:localization/localization.dart';
|
||||
import '../../business_logic/settings.dart' as settings;
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AppSettings extends StatelessWidget {
|
||||
const AppSettings({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text("post-batch-size".i18n()),
|
||||
Slider(
|
||||
value: 3,
|
||||
min: 3,
|
||||
max: 100,
|
||||
onChanged: ((value) {}),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,12 +2,15 @@ import 'package:flutter/material.dart';
|
|||
import 'package:localization/localization.dart';
|
||||
import './account.dart' as account;
|
||||
import './about.dart' as about;
|
||||
import './app.dart' as app;
|
||||
|
||||
Widget settings(context) {
|
||||
final List<Widget> categories = [
|
||||
SettingsPanel(
|
||||
title: "account-settings".i18n(),
|
||||
content: const account.AccountSettings()),
|
||||
SettingsPanel(
|
||||
title: "app-settings".i18n(), content: const app.AppSettings()),
|
||||
SettingsPanel(
|
||||
title: "about".i18n(),
|
||||
content: const about.AboutSettings(),
|
||||
|
|
|
@ -9,8 +9,9 @@ class Timeline extends StatefulWidget {
|
|||
State<Timeline> createState() => _TimelineState();
|
||||
}
|
||||
|
||||
class _TimelineState extends State<Timeline> {
|
||||
String? id;
|
||||
class _TimelineState extends State<Timeline>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
String? oldestId;
|
||||
final controller = ScrollController();
|
||||
List<Widget> children = [];
|
||||
bool loading = false;
|
||||
|
@ -18,12 +19,11 @@ class _TimelineState extends State<Timeline> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
for (int i = 0; i <= 20; i++) {
|
||||
fetchMore();
|
||||
}
|
||||
children.add(const LoadingBox());
|
||||
fetchMore();
|
||||
controller.addListener(() {
|
||||
if (controller.position.maxScrollExtent <=
|
||||
controller.offset + MediaQuery.of(context).size.height &&
|
||||
controller.offset + 2 * MediaQuery.of(context).size.height &&
|
||||
!loading) {
|
||||
fetchMore();
|
||||
}
|
||||
|
@ -36,18 +36,20 @@ class _TimelineState extends State<Timeline> {
|
|||
}
|
||||
loading = true;
|
||||
|
||||
final model = await tl.getTimelineFromServer(id);
|
||||
id = model.posts[model.posts.length - 1].id;
|
||||
|
||||
final models = await tl.getTimelineFromServer(oldestId);
|
||||
setState(() {
|
||||
if (children.isNotEmpty) {
|
||||
children.removeAt(children.length - 1);
|
||||
children.removeWhere((element) {
|
||||
return element.runtimeType != Thread;
|
||||
});
|
||||
|
||||
List<Thread> threads = [];
|
||||
for (int i = 0; i < models.length; i++) {
|
||||
threads.add(Thread(model: models[i]));
|
||||
}
|
||||
children.addAll([
|
||||
Thread(
|
||||
model: model,
|
||||
)
|
||||
]);
|
||||
|
||||
oldestId = models.last.posts.last.id;
|
||||
|
||||
children.addAll(threads);
|
||||
children.add(
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
@ -62,6 +64,7 @@ class _TimelineState extends State<Timeline> {
|
|||
],
|
||||
),
|
||||
);
|
||||
children.add(const LoadingBox());
|
||||
loading = false;
|
||||
});
|
||||
}
|
||||
|
@ -74,6 +77,7 @@ class _TimelineState extends State<Timeline> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return ListView.separated(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: controller,
|
||||
|
@ -90,4 +94,23 @@ class _TimelineState extends State<Timeline> {
|
|||
addAutomaticKeepAlives: false,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
}
|
||||
|
||||
class LoadingBox extends StatelessWidget {
|
||||
const LoadingBox({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox.fromSize(
|
||||
size: Size(double.infinity, MediaQuery.of(context).size.height),
|
||||
child: Center(
|
||||
child: SizedBox.fromSize(
|
||||
size: const Size(128, 128),
|
||||
child: const CircularProgressIndicator(),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,10 @@ class _MainScaffoldState extends State<MainScaffold> {
|
|||
];
|
||||
return Scaffold(
|
||||
extendBody: true,
|
||||
body: screens[index],
|
||||
body: IndexedStack(
|
||||
index: index,
|
||||
children: screens,
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||
floatingActionButton: buttons[index],
|
||||
bottomNavigationBar: BottomAppBar(
|
||||
|
|
|
@ -30,7 +30,11 @@ class ImageAttachmentDisplay extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Image.network(model.url, width: double.infinity),
|
||||
Image.network(
|
||||
model.url,
|
||||
width: double.infinity,
|
||||
fit: BoxFit.fitWidth,
|
||||
),
|
||||
AltText(text: model.description.toString())
|
||||
]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue