1 module main_page;
2 
3 import std.concurrency;
4 import std.file;
5 import std.json;
6 import std.typecons;
7 import std.stdio;
8 
9 import awebview.wrapper;
10 import awebview.gui.html;
11 import awebview.gui.datapack;
12 import awebview.gui.application;
13 import awebview.gui.activity;
14 import awebview.gui.widgets.button;
15 import awebview.gui.widgets.text;
16 
17 import graphite.twitter;
18 
19 import carbon.functional;
20 
21 import msgpack;
22 import lock_free.dlist;
23 
24 import consts;
25 import oauth_page;
26 import tweet_table;
27 
28 
29 class MainPage :  TemplateHTMLPage!(import(`main_page.html`))
30 {
31     private
32     alias NormalButton = InputButton!(["class": "btn btn-xs btn-primary"]);
33 
34     private
35     alias TweetTextArea = TextArea!();
36 
37     private
38     alias PackedDataType = DataPack!(bool, Twitter);
39 
40 
41     this()
42     {
43         super("mainPage");
44 
45         _tweetTable = new TweetTable("tweetTable");
46         this ~= _tweetTable;
47 
48         this ~= new TweetTextArea(`iptTweetText`);
49 
50         this ~= (new NormalButton(`btnTweet`)).observe!((a){
51             a.onClick.connect!"onClickTweet"(this);
52             a.staticProps["value"] = "ツイート";
53         });
54     }
55 
56 
57     override
58     void onStart(Activity activity)
59     {
60         if(auto p = this.id in activity.application.savedData){
61             auto origin = *p;
62             auto pd = PackedDataType.unpack(*p);
63 
64             if(pd.field[0])
65                 _twTkn = pd.field[1];
66 
67             *p = pd.parent;
68             super.onStart(activity);
69             *p = origin;
70         }
71         else
72         {
73             super.onStart(activity);
74         }
75     }
76 
77 
78     override
79     void onLoad(bool isInit)
80     {
81         super.onLoad(isInit);
82 
83         if(this._twTkn.isNull)
84         {
85             if(activity["oauthPage"].to!OAuthPage.token.isNull)
86                 activity.load("oauthPage");
87             else{
88                 _twTkn = activity["oauthPage"].to!OAuthPage.token;
89                 connectUserStream();
90             }
91         }
92         else
93             connectUserStream();
94     }
95 
96 
97     override
98     void onDestroy()
99     {
100         super.onDestroy();
101 
102         if(!_twTkn.isNull){
103             PackedDataType pd;
104 
105             if(auto p = this.id in SDLApplication.instance.savedData)
106                 pd.parent = *p;
107 
108             pd.field[0] = !_twTkn.isNull;
109             if(!_twTkn.isNull)
110                 pd.field[1] = _twTkn.get;
111 
112             SDLApplication.instance.savedData[this.id] = pd.pack();
113 
114             _usTid.send(false);    // send dummy message
115         }
116     }
117 
118 
119     void connectUserStream()
120     {
121         auto res = _twTkn.callAPI!"userstream.user"(null);
122         _us = res.channel;
123         _usTid = res.tid;
124     }
125 
126 
127     override
128     void onUpdate()
129     {
130         super.onUpdate();
131 
132         while(1)
133         {
134             if(auto p = _us.popFront()){
135                 try{
136                     string tw = *p;
137                     auto json = parseJSON(tw);
138                     _tweetTable.addTweet(json["user"]["profile_image_url"].str, json["user"]["name"].str, json["text"].str);
139                 }
140                 catch(Exception){}
141             }
142             else
143                 break;
144         }
145     }
146 
147 
148     void onClickTweet(FiredContext ctx, WeakRef!(const(JSArrayCpp)) args)
149     {
150         auto txtArea = elements["iptTweetText"].to!(TextArea!());
151 
152         auto tweetText = txtArea.text();
153         if(tweetText.length){
154             _twTkn.callAPI!"statuses.update"(["status": tweetText]);
155             txtArea.text = "";
156         }
157     }
158 
159 
160   private:
161     TweetTable _tweetTable;
162     Nullable!Twitter _twTkn;
163     shared(AtomicDList!string) _us;
164     Tid _usTid;
165 }