billing_questions_widget.dart 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import 'dart:convert';
  2. import 'package:flutter/material.dart';
  3. import 'package:photos/core/network.dart';
  4. import 'package:photos/ui/expansion_card.dart';
  5. import 'package:photos/ui/loading_widget.dart';
  6. class BillingQuestionsWidget extends StatelessWidget {
  7. const BillingQuestionsWidget({
  8. Key key,
  9. }) : super(key: key);
  10. @override
  11. Widget build(BuildContext context) {
  12. return FutureBuilder(
  13. future: Network.instance
  14. .getDio()
  15. .get("https://static.ente.io/faq.json")
  16. .then((response) {
  17. final faqItems = <FaqItem>[];
  18. for (final item in response.data as List) {
  19. faqItems.add(FaqItem.fromMap(item));
  20. }
  21. return faqItems;
  22. }),
  23. builder: (BuildContext context, AsyncSnapshot snapshot) {
  24. if (snapshot.hasData) {
  25. final faqs = <Widget>[];
  26. faqs.add(Padding(
  27. padding: const EdgeInsets.all(24),
  28. child: Text(
  29. "faqs",
  30. style: TextStyle(
  31. fontSize: 18,
  32. fontWeight: FontWeight.bold,
  33. ),
  34. ),
  35. ));
  36. for (final faq in snapshot.data) {
  37. faqs.add(FaqWidget(faq: faq));
  38. }
  39. faqs.add(Padding(
  40. padding: EdgeInsets.all(16),
  41. ));
  42. return SingleChildScrollView(
  43. child: Column(
  44. children: faqs,
  45. ),
  46. );
  47. } else {
  48. return loadWidget;
  49. }
  50. },
  51. );
  52. }
  53. }
  54. class FaqWidget extends StatelessWidget {
  55. const FaqWidget({
  56. Key key,
  57. @required this.faq,
  58. }) : super(key: key);
  59. final FaqItem faq;
  60. @override
  61. Widget build(BuildContext context) {
  62. return ExpansionCard(
  63. title: Text(faq.q),
  64. color: Theme.of(context).buttonColor,
  65. children: [
  66. Padding(
  67. padding: const EdgeInsets.only(left: 16, right: 16),
  68. child: Text(
  69. faq.a,
  70. style: TextStyle(
  71. height: 1.5,
  72. ),
  73. ),
  74. )
  75. ],
  76. );
  77. }
  78. }
  79. class FaqItem {
  80. final String q;
  81. final String a;
  82. FaqItem({
  83. this.q,
  84. this.a,
  85. });
  86. FaqItem copyWith({
  87. String q,
  88. String a,
  89. }) {
  90. return FaqItem(
  91. q: q ?? this.q,
  92. a: a ?? this.a,
  93. );
  94. }
  95. Map<String, dynamic> toMap() {
  96. return {
  97. 'q': q,
  98. 'a': a,
  99. };
  100. }
  101. factory FaqItem.fromMap(Map<String, dynamic> map) {
  102. if (map == null) return null;
  103. return FaqItem(
  104. q: map['q'],
  105. a: map['a'],
  106. );
  107. }
  108. String toJson() => json.encode(toMap());
  109. factory FaqItem.fromJson(String source) =>
  110. FaqItem.fromMap(json.decode(source));
  111. @override
  112. String toString() => 'FaqItem(q: $q, a: $a)';
  113. @override
  114. bool operator ==(Object o) {
  115. if (identical(this, o)) return true;
  116. return o is FaqItem && o.q == q && o.a == a;
  117. }
  118. @override
  119. int get hashCode => q.hashCode ^ a.hashCode;
  120. }