diff --git a/lib/cubit/file_list_load_bloc.dart b/lib/cubit/file_list_load_bloc.dart new file mode 100644 index 0000000..64551ea --- /dev/null +++ b/lib/cubit/file_list_load_bloc.dart @@ -0,0 +1,28 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:gitea_client/model/File.dart'; + +import '../service/gitea_service.dart'; + +part 'file_list_load_event.dart'; + +part 'file_list_load_state.dart'; + +class FileListLoadBloc extends Bloc { + final GiteaService giteaService; + FileListLoadBloc({required this.giteaService}) : super(const FileListLoadState()) { + on(_FileListLoadState); + } + + Future _FileListLoadState( + FileListLoadPathEvent event, Emitter emit) async { + if(event.repoName.isEmpty) return; + emit(FileListLoadState(status: FileLoadStatus.loading)); + final fileListResult = await giteaService.getFolder( + event.repoName.split('/')[0], event.repoName.split('/')[1], event.path); + return emit(FileListLoadState(status: FileLoadStatus.success,files: fileListResult,path: event.path,repoFullname: event.repoName)); + + } +} diff --git a/lib/cubit/file_list_load_event.dart b/lib/cubit/file_list_load_event.dart new file mode 100644 index 0000000..2134b97 --- /dev/null +++ b/lib/cubit/file_list_load_event.dart @@ -0,0 +1,15 @@ +part of 'file_list_load_bloc.dart'; + +abstract class FileListLoadEvent extends Equatable { + const FileListLoadEvent(); +} + +class FileListLoadPathEvent extends FileListLoadEvent { + + final repoName; + final path; + const FileListLoadPathEvent(this.path, this.repoName); + @override + List get props => [path,repoName]; + +} \ No newline at end of file diff --git a/lib/cubit/file_list_load_state.dart b/lib/cubit/file_list_load_state.dart new file mode 100644 index 0000000..ab2cd37 --- /dev/null +++ b/lib/cubit/file_list_load_state.dart @@ -0,0 +1,15 @@ +part of 'file_list_load_bloc.dart'; + +enum FileLoadStatus { loading, success,failure } + +class FileListLoadState extends Equatable { + const FileListLoadState({this.path="", this.repoFullname ="", this.error_message = null, this.files= const [],this.status = FileLoadStatus.loading}); + final FileLoadStatus status; + final String path; + final String repoFullname; + final String? error_message; + final List files; + + @override + List get props => [path,repoFullname]; +} \ No newline at end of file diff --git a/lib/widget/repo_overview.dart b/lib/widget/repo_overview.dart index dced1b7..51d50bc 100644 --- a/lib/widget/repo_overview.dart +++ b/lib/widget/repo_overview.dart @@ -2,7 +2,9 @@ import 'dart:convert'; import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:gitea_client/cubit/file_list_load_bloc.dart'; import 'package:gitea_client/model/repository.dart'; import 'package:gitea_client/model/user.dart'; import 'package:gitea_client/service/gitea_service.dart'; @@ -147,13 +149,18 @@ class _RepoHome extends State { width: (media.width > 600) ? media.width * 0.6 : media.width * 0.9, - - height: media.height - padding.top - padding.bottom -kToolbarHeight -kBottomNavigationBarHeight-30, + height: media.height - + padding.top - + padding.bottom - + kToolbarHeight - + kBottomNavigationBarHeight - + 30, child: Column( - children: [ - Expanded(child: Markdown(selectable: true, data: content)), - ], - )), + children: [ + Expanded( + child: Markdown(selectable: true, data: content)), + ], + )), ); } else { return const Center( @@ -201,73 +208,72 @@ class _RepoFiles extends State { @override Widget build(BuildContext context) { - return FutureBuilder>( - 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( + return BlocProvider( + create: (context) { + return FileListLoadBloc( + giteaService: GiteaService(apiAccess: widget.user.apiAccess)) + ..add(FileListLoadPathEvent("/", widget.repo.fullName!)); + }, + child: BlocBuilder( + builder: (context, state) { + switch (state.status) { + case FileLoadStatus.failure: + String error_message = state.error_message!; + return Center(child: Text('failed to fetch $error_message')); + case FileLoadStatus.success: + if (state.files.isEmpty) { + return const Center( + child: Text('No files in current directory')); + } + var files = (state.path == "/") + ? [] + : [ + RepoFile( + name: "..", + path: state.path, + sha: "", + type: "dir", + size: 0, + url: "", + htmlUrl: "", + gitUrl: "", + lLinks: Links(self: "", git: "", html: "")) + ]; + files.addAll(state.files); + 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(), - ); + onTap: () { + if (files[index].type == "dir") { + String prev = files[index].path.contains("/") + ? files[index].path.substring( + 0, files[index].path.lastIndexOf('/')) + : "/"; + path = (files[index].name == "..") + ? prev + : files[index].path; + context.read().add(FileListLoadPathEvent(path,widget.repo.fullName!)); + } 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, + ); + default: + return const Center(child: CircularProgressIndicator()); } - }); + }, + ), + ); } } @@ -306,7 +312,7 @@ class _RepoIssues extends State { Widget build(BuildContext context) { return DefaultTabController( length: 2, - child:DefaultTabController( + child: DefaultTabController( length: 2, child: Scaffold( appBar: PreferredSize( @@ -328,10 +334,10 @@ class _RepoIssues extends State { body: TabBarView( children: [ Column( - children: const [Text("Lunches Page")], + children: const [Text("Open Issues")], ), - Column( - children: const [ Text("Cart Page")], + Column( + children: const [Text("Closed Issues")], ) ], ),