Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 6.99 KB | None | 0 0
  1. import 'package:flutter/material.dart';
  2. import 'package:after_layout/after_layout.dart';
  3. import 'dart:async';
  4.  
  5. import 'questions.dart';
  6. import 'life_history.dart';
  7. import 'alert.dart';
  8.  
  9. // Textstyle of the heading used in Age
  10. TextStyle heading = TextStyle(
  11.     fontWeight: FontWeight.bold,
  12.     fontSize: 16,
  13.   );
  14.  
  15. // Textstyle of the heading used in Month
  16. TextStyle subhead = TextStyle(
  17.     fontStyle: FontStyle.italic,
  18.   );
  19.  
  20. class LifeTab extends StatefulWidget {
  21.   LifeTab({Key key}) : super(key: key);
  22.  
  23.   @override
  24.   _LifeTabState createState() => _LifeTabState();
  25. }
  26.  
  27. class _LifeTabState extends State<LifeTab> with AfterLayoutMixin<LifeTab>{
  28.   // "historyList" => Past events retrieved from db
  29.   // "time" => 0-12 in year 0, 13-24 in year 1 ...
  30.   // "processedTime" => only for headings
  31.   // "processedAge" => only for headings
  32.   List<Widget> historyList = [];
  33.   int time = -1;
  34.   int processedTime = -1;
  35.   int processedAge = -1;
  36.   ScrollController _scrollController = new ScrollController();
  37.  
  38.   // Reads previous history from database and formats them
  39.   @override
  40.   void initState(){
  41.     super.initState();
  42.    
  43.     // Read history
  44.     getAllHistory().then((history){
  45.       setState((){
  46.         // Go through every entry in our history db
  47.         for (int i = 0; i<history.length; i++){
  48.           var entry = history[i];
  49.           var outcome;
  50.  
  51.           if (time < entry.time){
  52.             outcome = RichText(
  53.               text: TextSpan(
  54.                 style: DefaultTextStyle.of(context).style,
  55.                 children: <TextSpan>[
  56.                   TextSpan(text: 'Month '+(entry.time%12).toString() + " — ",
  57.                     style: subhead,),
  58.                   TextSpan(text: entry.outcome,),
  59.                 ],
  60.               ),
  61.             );
  62.           } else {
  63.             outcome = Text(entry.outcome);
  64.           }
  65.  
  66.           // If time of entry % 12 is 0, a.k.a a year,
  67.           if (entry.time % 12 == 0){
  68.             int age = i~/12;
  69.  
  70.             // Obtain the year and check if we have processed that age heading
  71.             if (age>processedAge){
  72.               historyList.add(Text(
  73.                 '\nAge: '+age.toString()+' years old',
  74.                 style: heading,)
  75.               );
  76.               // After we have processed the heading, add to addedAge to show we processed that age
  77.               processedAge += 1;
  78.             }
  79.           }
  80.  
  81.           // Make sure we update the current time to be the latest entry time
  82.           time = entry.time;
  83.           historyList.add(outcome);
  84.         }
  85.       });
  86.       _scrollController.jumpTo(_scrollController.position.maxScrollExtent);
  87.     });
  88.   }
  89.  
  90.   @override
  91.   void afterFirstLayout(BuildContext context){
  92.     //Timer(Duration(milliseconds: 100), () => _scrollController.animateTo(_scrollController.position.maxScrollExtent, duration: const Duration(milliseconds: 100), curve: Curves.easeOut));
  93.     _scrollController.jumpTo(_scrollController.position.maxScrollExtent);
  94.     scheduleMicrotask(() => _scrollController.jumpTo(_scrollController.position.maxScrollExtent));
  95.   }
  96.  
  97.   Widget monthHeading(text){
  98.     if (processedTime < time){
  99.       processedTime += 1;
  100.       return RichText(
  101.         text: TextSpan(
  102.           style: DefaultTextStyle.of(context).style,
  103.           children: <TextSpan>[
  104.             TextSpan(
  105.               text: 'Month '+(time%12).toString() + " — ",
  106.               style: subhead,),
  107.             TextSpan(text: text,),
  108.           ],
  109.         ),
  110.       );
  111.     } else {
  112.       return  Text(text);
  113.     }
  114.   }
  115.  
  116.   void questionRecursive({id, text}) async {
  117.     if (text != null){
  118.       var split = text.split('|');
  119.       simpleAlert(context, split[0], split[1]);
  120.       return;
  121.     }
  122.     Question data;
  123.    
  124.     if (id == null){
  125.       data = await getRandomQuestion(time);
  126.     } else {
  127.       data = await getQuestionById(id);
  128.     }
  129.  
  130.     if (data == null){
  131.       insertHistory(History(
  132.         outcome: "Nothing interesting happened.\n",
  133.         time: time,
  134.         questionId: -1,
  135.       ));
  136.       setState((){historyList.add(monthHeading("Nothing interesting happened.\n"));});
  137.       return;
  138.     }
  139.  
  140.     var choices = data.choices.split(';');
  141.     var consequences = data.consequences.split(';');
  142.     List<Function> consequenceList = [];
  143.    
  144.     for (int i = 0; i<choices.length;i++){
  145.       var split = consequences[i].split(">");
  146.       String textbox =  split[2];
  147.       String historyText = split[0];
  148.  
  149.       var formatted = historyText;
  150.      
  151.       Function onPress;
  152.       if (textbox.substring(0,6) == "GO TO "){
  153.         onPress = (){
  154.           Navigator.pop(context);
  155.            insertHistory(History(
  156.             outcome: formatted,
  157.             time: time,
  158.             questionId: data.id,
  159.           ));
  160.  
  161.           setState((){historyList.add(monthHeading(formatted));});
  162.           questionRecursive(id: textbox.substring(6));
  163.         };
  164.       } else {
  165.         onPress = (){
  166.           Navigator.pop(context);
  167.           formatted = historyText + "\n";
  168.           insertHistory(History(
  169.             outcome: formatted,
  170.             time: time,
  171.             questionId: data.id,
  172.           ));
  173.  
  174.           setState((){historyList.add(monthHeading(formatted));});
  175.           questionRecursive(text: textbox);
  176.         };
  177.       }
  178.       consequenceList.add(onPress);
  179.       }
  180.     var question = data.question.split('|');
  181.     multiChoiceAlert(context, question[0], question[1], choices, consequenceList);
  182.   }
  183.  
  184.   void onPlusTap() async{
  185.     time += 1;
  186.     setState(() {
  187.       if (time % 12 == 0 && (time~/12) > processedAge){
  188.         historyList.add(Text(
  189.           "\nAge "+(time~/12).toString()+" years old",
  190.           style: heading,
  191.         ));
  192.         processedAge += 1;
  193.       }
  194.          
  195.       questionRecursive();
  196.     });
  197.     _scrollController.animateTo(_scrollController.position.maxScrollExtent, duration: const Duration(milliseconds: 500), curve: Curves.easeOut);
  198.   }
  199.  
  200.   Widget _buildEvent(BuildContext context, int index){
  201.     return historyList[index];
  202.   }
  203.  
  204.   @override
  205.   Widget build(BuildContext context) {
  206.    
  207.     // This method is rerun every time setState is called, for instance as done
  208.     // by the _incrementCounter method above.
  209.     //
  210.     // The Flutter framework has been optimized to make rerunning build methods
  211.     // fast, so that you can just rebuild anything that needs updating rather
  212.     // than having to individually change instances of widgets.
  213.     return Scaffold(
  214.       body: ListView.builder(    
  215.         controller: _scrollController,
  216.         padding: EdgeInsets.only(
  217.           top: 40,
  218.           left: 20,
  219.           right: 20,
  220.           bottom: 400,
  221.         ),
  222.         shrinkWrap: true,
  223.         itemCount: historyList.length,
  224.         itemBuilder: _buildEvent,
  225.       ),
  226.       floatingActionButton: FloatingActionButton(
  227.         onPressed: onPlusTap,
  228.         tooltip: 'Age up',
  229.         child: Icon(Icons.add),
  230.       ), // This trailing comma makes auto-formatting nicer for build methods.
  231.     );
  232.   }
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement