Basic code page
Some checks failed
ci/woodpecker/push/flutterBuild Pipeline failed

This commit is contained in:
Bazsalanszky 2022-05-15 18:51:38 +02:00
parent 0f052d018c
commit 182588e7ae
Signed by: Bazsalanszky
GPG key ID: B40814F4EFE23F96
6 changed files with 277 additions and 9 deletions

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:gitea_client/model/repouser.dart';
import 'package:gitea_client/model/user.dart';
import 'package:gitea_client/widget/code_page.dart';
import 'package:gitea_client/widget/login_form.dart';
import 'package:gitea_client/widget/login_status.dart';
import 'package:gitea_client/widget/repo_list_page.dart';
@ -48,6 +49,12 @@ class MyApp extends StatelessWidget {
settings: const RouteSettings(name: "/repopage"),
builder: (context) =>
RepoPage(repo: repouser.repository, user: repouser.user));
case "/fileview":
final data = route.arguments as CodePageData;
return MaterialPageRoute(
settings: const RouteSettings(name: "/fileview"),
builder: (context) =>
CodePage(filePath: data.filePath, repo: data.repo, owner: data.owner, user: data.user));
}
return null;
},

View file

@ -35,6 +35,23 @@ class GiteaService {
return RepoFile.fromJson(jsonDecode(response.body));
}
Future<List<RepoFile>> getFolder(String owner,String repo,String path) async{
var response = await http.get(
Uri.https(apiAccess.instance, "api/v1/repos/$owner/$repo/contents/$path", {
"token": apiAccess.token,
}),
);
if (response.statusCode == 200) {
final body = json.decode(response.body) as List;
var result = body.map((dynamic json) {
return RepoFile.fromJson(json);
}).toList();
result.sort((a,b) => a.type.compareTo(b.type));
return result;
}
throw Exception('error fetching files');
}
//
Future<List<Repository>> getUserRepositories([int page = 1, int limit = 10]) async{
var response = await http.get(

95
lib/widget/code_page.dart Normal file
View file

@ -0,0 +1,95 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_highlight/flutter_highlight.dart';
import 'package:flutter_highlight/themes/github.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:gitea_client/model/user.dart';
import 'package:gitea_client/service/gitea_service.dart';
import '../model/File.dart';
class CodePageData {
final String filePath;
final String repo;
final String owner;
final SavedUser user;
const CodePageData(this.filePath, this.repo, this.owner, this.user);
}
class CodePage extends StatefulWidget {
final String filePath;
final String repo;
final String owner;
final SavedUser user;
const CodePage(
{Key? key,
required this.filePath,
required this.repo,
required this.owner,
required this.user})
: super(key: key);
@override
_CodePage createState() => _CodePage();
}
class _CodePage extends State<CodePage> {
Future<RepoFile>? fileRequest;
@override
void initState() {
GiteaService giteaService = GiteaService(apiAccess: widget.user.apiAccess);
fileRequest =
giteaService.getFile(widget.owner, widget.repo, widget.filePath);
}
@override
Widget build(context) {
final media = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: Text(widget.filePath),
),
body: FutureBuilder<RepoFile>(
future: fileRequest,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Column(
children: [
Text("No Readme file found!",
style: Theme.of(context).textTheme.headline6),
],
),
);
} else if (snapshot.hasData) {
final file = snapshot.data!;
final content = utf8.decode(base64.decode(file.content!));
return Center(
child: SizedBox(
width:
(media.width > 600) ? media.width * 0.6 : media.width * 0.9,
height: media.height * 0.7,
child: (file.name.endsWith(".md"))
? Markdown(selectable: true, data: content)
: SingleChildScrollView(
child: HighlightView(
content,
language: "dart",
theme: githubTheme,
)),
));
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
}),
);
}
}

View file

@ -6,6 +6,7 @@ import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:gitea_client/model/repository.dart';
import 'package:gitea_client/model/user.dart';
import 'package:gitea_client/service/gitea_service.dart';
import 'package:gitea_client/widget/code_page.dart';
import '../model/File.dart';
@ -121,8 +122,10 @@ class _RepoHome extends State<RepoHome> {
final media = MediaQuery.of(context).size;
return Column(children: [
Text(widget.repo.fullName!,
style: Theme.of(context).textTheme.headline3,),
Text(
widget.repo.fullName!,
style: Theme.of(context).textTheme.headline3,
),
FutureBuilder<RepoFile>(
future: readmeRequest,
builder: (context, snapshot) {
@ -139,10 +142,13 @@ class _RepoHome extends State<RepoHome> {
var file = snapshot.data!;
final content = utf8.decode(base64.decode(file.content!));
return SingleChildScrollView(child: Center(
return SingleChildScrollView(
child: Center(
child: SizedBox(
width: (media.width > 600) ? media.width * 0.6 : media.width*0.9,
height: media.height*0.7,
width: (media.width > 600)
? media.width * 0.6
: media.width * 0.9,
height: media.height * 0.7,
child: Markdown(selectable: true, data: content)),
));
} else {
@ -177,10 +183,106 @@ class RepoFiles extends StatefulWidget {
}
class _RepoFiles extends State<RepoFiles> {
String path = "/";
Future<List<RepoFile>>? readmeRequest;
late final GiteaService giteaService;
final _scrollController = ScrollController();
@override
void initState() {
giteaService = GiteaService(apiAccess: widget.user.apiAccess);
readmeRequest = giteaService.getFolder(
widget.repo.owner.username!, widget.repo.name, path);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
return FutureBuilder<List<RepoFile>>(
future: readmeRequest,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Column(
children: [
Text("No Readme file found!",
style: Theme.of(context).textTheme.headline6),
],
),
);
} else if (snapshot.hasData) {
var files = (path == "/")
? []
: [
RepoFile(
name: "..",
path: path,
sha: "",
type: "dir",
size: 0,
url: "",
htmlUrl: "",
gitUrl: "",
lLinks: Links(self: "", git: "", html: ""))
];
files.addAll(snapshot.data!);
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return FileListItem(
file: files[index],
onTap: () => {
if (files[index].type == "dir")
setState(() {
String prev = files[index].path.contains("/")
? files[index].path.substring(
0, files[index].path.lastIndexOf('/'))
: "/";
path = (files[index].name == "..")
? prev
: files[index].path;
readmeRequest = null;
readmeRequest = giteaService.getFolder(
widget.repo.owner.username!,
widget.repo.name,
path);
})
else
Navigator.of(context).pushNamed("/fileview",
arguments: CodePageData(
files[index].path,
widget.repo.name,
widget.repo.owner.username!,
widget.user))
});
},
itemCount: files.length,
controller: _scrollController,
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
});
}
}
class FileListItem extends StatelessWidget {
final RepoFile file;
final Function onTap;
const FileListItem({Key? key, required this.file, required this.onTap})
: super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
leading: (file.type == "file")
? const Icon(Icons.insert_drive_file_outlined)
: const Icon(Icons.folder_outlined),
title: Text(file.name),
onTap: () => {onTap()},
);
}
}
@ -198,8 +300,40 @@ class RepoIssues extends StatefulWidget {
class _RepoIssues extends State<RepoIssues> {
@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
return DefaultTabController(
length: 2,
child:DefaultTabController(
length: 2,
child: Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(kToolbarHeight),
child: Container(
color: Colors.lightGreen, ,
child: SafeArea(
child: Column(
children: <Widget>[
Expanded(child: Container()),
const TabBar(
tabs: [Text("Open"), Text("Closed")],
),
],
),
),
),
),
body: TabBarView(
children: <Widget>[
Column(
children: const [Text("Lunches Page")],
),
Column(
children: const [ Text("Cart Page")],
)
],
),
),
),
);
}
}

View file

@ -174,6 +174,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "8.0.1"
flutter_highlight:
dependency: "direct main"
description:
name: flutter_highlight
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.0"
flutter_lints:
dependency: "direct dev"
description:
@ -210,6 +217,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
highlight:
dependency: transitive
description:
name: highlight
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.0"
http:
dependency: "direct main"
description:

View file

@ -46,6 +46,7 @@ dependencies:
shared_preferences: ^2.0.13
badges: ^2.0.2
flutter_markdown: ^0.6.10
flutter_highlight: ^0.7.0
dev_dependencies:
flutter_test: