Skip to content

Instantly share code, notes, and snippets.

@ProZhar
Forked from eduardoflorence/main.dart
Created February 18, 2023 13:17
Show Gist options
  • Select an option

  • Save ProZhar/a42e58bf62e5b7b182b6db00988423b1 to your computer and use it in GitHub Desktop.

Select an option

Save ProZhar/a42e58bf62e5b7b182b6db00988423b1 to your computer and use it in GitHub Desktop.

Revisions

  1. @eduardoflorence eduardoflorence created this gist Apr 1, 2021.
    181 changes: 181 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,181 @@
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';

    void main() {
    runApp(GetMaterialApp(
    initialRoute: '/home',
    getPages: [
    GetPage(
    name: '/home',
    page: () => HomePage(),
    ),
    GetPage(
    name: '/git-repositories',
    page: () => GitRepositoryPage(),
    binding: GitRepositoryBinding(),
    ),
    ],
    ));
    }

    class HomePage extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(title: Text('HOME')),
    body: Center(
    child: ElevatedButton(
    onPressed: () => Get.toNamed('/git-repositories'),
    child: Text('View GitHub Repositories'),
    ),
    ),
    );
    }
    }

    class GitRepositoryBinding extends Bindings {
    @override
    void dependencies() {
    Get.lazyPut(() => GitRepositoryProvider());
    Get.put(GitRepositoryController(provider: Get.find()));
    }
    }

    class GitRepositoryModel {
    GitRepositoryModel({
    required this.fullName,
    required this.description,
    required this.url,
    });

    String fullName;
    String description;
    String url;

    factory GitRepositoryModel.fromJson(Map<String, dynamic> json) =>
    GitRepositoryModel(
    fullName: json['full_name'],
    description: json['description'] ?? 'No description',
    url: json['html_url'],
    );

    static List<GitRepositoryModel> listFromJson(list) =>
    List<GitRepositoryModel>.from(
    list.map((x) => GitRepositoryModel.fromJson(x)));
    }

    class GitRepositoryController extends GetxController
    with StateMixin<List<GitRepositoryModel>>, ScrollMixin {
    final GitRepositoryProvider provider;
    GitRepositoryController({required this.provider});

    List<GitRepositoryModel> repositories = [];
    final int repositoriesPerPage = 10;
    int page = 1;
    bool getFirstData = false;
    bool lastPage = false;

    @override
    void onInit() {
    findAllGitRepositories();
    super.onInit();
    }

    Future<void> findAllGitRepositories() async {
    await provider.getGitRepositories(repositoriesPerPage, page).then((result) {
    final bool emptyRepositories = result.body?.isEmpty ?? true;
    if (!getFirstData && emptyRepositories) {
    change(null, status: RxStatus.empty());
    } else if (getFirstData && emptyRepositories) {
    lastPage = true;
    } else {
    getFirstData = true;
    repositories.addAll(result.body!);
    change(repositories, status: RxStatus.success());
    }
    }, onError: (err) {
    change(null, status: RxStatus.error(err.toString()));
    });
    }

    @override
    Future<void> onEndScroll() async {
    print('onEndScroll');
    if (!lastPage) {
    page += 1;
    Get.dialog(Center(child: LinearProgressIndicator()));
    await findAllGitRepositories();
    Get.back();
    } else {
    Get.snackbar('Alert', 'End of Repositories');
    }
    }

    @override
    Future<void> onTopScroll() async {
    print('onTopScroll');
    }
    }

    class GitRepositoryProvider extends GetConnect {
    final String org = 'flutter';

    @override
    void onInit() {
    // All request will pass to jsonEncode so CasesModel.fromJson()
    httpClient.defaultDecoder = GitRepositoryModel.listFromJson;
    httpClient.baseUrl = 'https://api.github.com/orgs';
    }

    Future<Response<List<GitRepositoryModel>>> getGitRepositories(
    int itemsPerPage, int page) =>
    get<List<GitRepositoryModel>>(
    '/$org/repos?per_page=$itemsPerPage&page=$page',
    // query: {'orderBy': 'nome'},
    decoder: GitRepositoryModel.listFromJson,
    );
    }

    class GitRepositoryPage extends GetView<GitRepositoryController> {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(title: Text('Repositories')),
    body: Container(
    child: controller.obx(
    (state) => ListView.builder(
    controller: controller.scroll,
    itemCount: state?.length,
    itemBuilder: (context, index) {
    final GitRepositoryModel repository = state![index];
    return ListTile(
    isThreeLine: true,
    leading: Text(
    (++index).toString(),
    style: TextStyle(fontSize: 20),
    ),
    title: Text(repository.fullName),
    subtitle:
    Text('${repository.description}\n${repository.url}'),
    );
    },
    ),
    onLoading: Center(child: LinearProgressIndicator()),
    onEmpty: Center(
    child: Text(
    'Repositories no found',
    style: TextStyle(fontSize: 18),
    textAlign: TextAlign.center,
    ),
    ),
    onError: (error) => Center(
    child: Text(
    'Error: Cannot get repositories \n$error',
    style: TextStyle(fontSize: 18),
    textAlign: TextAlign.center,
    ),
    ),
    ),
    ));
    }
    }