root/platform/air/wasaco/src/wasaco.mxml @ 17646

Revision 17646, 19.4 kB (checked in by kan, 6 years ago)

イイネ解除に対応した

Line 
1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application
3        xmlns:mx="http://www.adobe.com/2006/mxml"
4        layout="absolute"
5        height="504"
6        width="400"
7        cornerRadius="4"
8        applicationComplete="init()"
9         xmlns:ns1="*">
10    <mx:Script>
11    <![CDATA[
12        import vc.kan.util.Template;
13        import mx.events.CloseEvent;
14        import flash.net.URLRequestDefaults;
15        import mx.events.ResizeEvent;
16        import mx.managers.SystemManager;
17        import mx.controls.Alert;
18                import mx.controls.Text;
19                import mx.controls.Image;
20                import mx.containers.TitleWindow;
21        import mx.managers.PopUpManager;
22        import vc.kan.net.Wassr;
23        import vc.kan.data.DBObject;
24            import mx.formatters.DateFormatter;
25           
26            [Embed(source="assets/feed.tt", mimeType="application/octet-stream")]
27            private var feedTmpl:Class;
28           
29            [Embed(source="assets/feed_channel.tt", mimeType="application/octet-stream")]
30            private var feedChannelTmpl:Class;
31       
32            [Embed(source="assets/style.tt", mimeType="application/octet-stream")]
33            private var feedStyleTmpl:Class;
34       
35                public var timer:Timer = new Timer(60000);
36               
37                private var feed_view:Array = new Array(20);
38               
39                private var wassr:Wassr;
40               
41                public var user_id:String;
42                public var password:String;
43               
44                public var feed_item:Object;
45                private var iine_map:Object;
46               
47                private var verXML:XML;
48
49                private var settingDb:DBObject = new DBObject(Setting);
50                private var setting:Object;
51               
52                private function init():void
53                {
54                        URLRequestDefaults.userAgent = "wasaco/"+version()+"; http://fushihara.net/wasaco.html";
55                       
56                        this.panel.title = "wasaco ver " + version();
57                        this.panel.addEventListener( MouseEvent.MOUSE_DOWN, doDrag );
58                        this.panel.addEventListener( MouseEvent.MOUSE_UP, savePosition );
59                        this.minimizeBtn.addEventListener( MouseEvent.MOUSE_UP, onMinimize );
60                        this.closeBtn.addEventListener( MouseEvent.MOUSE_UP, onClose );
61                        this.resizeBtn.addEventListener( MouseEvent.MOUSE_DOWN, startResize );
62                        this.resizeBtn.addEventListener( MouseEvent.MOUSE_UP, saveWindowSize );
63                        stage.addEventListener(Event.RESIZE, onResize);
64                        this.feedCanvas.addEventListener( Event.COMPLETE, feedLinkHook );
65                        this.feedCanvas.htmlLoader.paintsDefaultBackground = false;
66                        this.feedCanvas.htmlLoader.navigateInSystemBrowser = true;
67                        XML.prettyPrinting = false;
68                        iine_map = {};
69                       
70                        var mine:wasaco = this;
71                        settingDb.find(function (settings:Array):void {
72                                setting = {
73                                        backColor: 0,
74                                        backAlpha: 0.8,
75                                        fontColor: "FFFFFF",
76                                        fontSize: 10,
77                                        windowWidth: 400,
78                                        windowHeight: 500,
79                                        windowX: 100,
80                                        windowY: 100
81                                };
82                                settings.forEach(function(conf:*, idx:Number, arr:Array):void {
83                                        setting[conf.key] = conf.value;
84                                });
85                                panel.setStyle("backgroundColor", setting.backColor);
86                                panel.setStyle("backgroundAlpha", setting.backAlpha);
87                                panel.setStyle("color", setting.fontColor);
88                                alwaysFrontChk.setStyle("color", setting.fontColor);
89                                message.setStyle("color", setting.fontColor);
90                                stage.nativeWindow.width = setting.windowWidth;
91                                stage.nativeWindow.height = setting.windowHeight;
92                                stage.nativeWindow.x = setting.windowX;
93                                stage.nativeWindow.y = setting.windowY;
94                        });
95                        showLoginWindow();
96                }
97               
98                private function initReplies():void {
99                        this.repliesCanvas.addEventListener( Event.COMPLETE, feedLinkHook );
100                        this.repliesCanvas.htmlLoader.paintsDefaultBackground = false;
101                        this.repliesCanvas.htmlLoader.navigateInSystemBrowser = true;
102                        get_feed();
103                }
104               
105                private function initChannel():void {
106                        this.channelCanvas.addEventListener( Event.COMPLETE, feedLinkHook );
107                        this.channelCanvas.htmlLoader.paintsDefaultBackground = false;
108                        this.channelCanvas.htmlLoader.navigateInSystemBrowser = true;
109                        get_channel_list();
110                }
111               
112                private function doDrag(event:MouseEvent):void {
113                        if ( this.panel.contains(event.target as DisplayObject) ) return;
114                        applicationDragHandler(event);
115                }
116               
117                private function feedLinkHook(event:Event):void {
118                        var links:Object = event.target.htmlLoader.window.document.links;
119                        for (var i:uint=0; i < links.length; i++) {
120                                if ( links[i].className == "comment" ) {
121                                        links[i].addEventListener("click", replyClick);
122                                } else if ( links[i].className == "iine" ) {
123                                        links[i].addEventListener("click", iineClick);
124                                } else {
125                                        links[i].addEventListener("mouseover", overLink);
126                                }
127                        }
128                }
129
130                private function overLink(evt:Object):void {
131                        var url:String = evt.target.href;
132                        if (url == null) return;
133                        message.text = url.replace(/http:\/\/wassr\.jp/, "");
134                }
135
136                private function replyClick(evt:Object):void {
137                        var comment:commentWindow = commentWindow(
138                                PopUpManager.createPopUp(this, commentWindow, true)
139                        );
140                        comment.target = this;
141                        comment.res_rid = evt.target.title;
142                        PopUpManager.centerPopUp(comment);
143                }
144
145                private function iineClick(evt:Object):void {
146                        if ( iine_map[evt.target.title] == 1 ) {
147                                wassr.unFavStatus(evt.target.title, function():void{
148                                        iine_map[evt.target.title] = 0;
149                                        evt.target.src = "app:/assets/normal.png";
150                                });
151                        } else {
152                                wassr.favStatus(evt.target.title, function():void{
153                                        iine_map[evt.target.title] = 1;
154                                        evt.target.src = "app:/assets/good.png";
155                                });
156                        }
157                }
158
159                public function saveSetting(key:String, value:*):void
160                {
161                        settingDb.find(function(settings:Array):void{
162                                if ( settings[0] ) {
163                                        settings[0].update({
164                                                "value": value
165                                        });
166                                }
167                        }, { "key": key }, null,
168                        function():void {
169                                settingDb.create({
170                                        "key": key,
171                                        "value": value
172                                }, function ():void {});
173                        });
174                }
175               
176                public function startAutoGetFeed():void
177                {
178                        updateCheck();
179                        timer.addEventListener(TimerEvent.TIMER, timerHandler);
180                        timer.start();
181                }
182               
183                private function showLoginWindow():void
184                {
185                        var login:loginWindow = loginWindow(
186                                PopUpManager.createPopUp(this, loginWindow, true)
187                        );
188                        login.target = this;
189                        login.loadProfile();
190                        PopUpManager.centerPopUp(login);
191                }
192               
193                public function get_feed():void
194                {
195                        if (!wassr) {
196                                wassr = new Wassr(user_id, password, URLRequestDefaults.userAgent);
197                                wassr.addEventListener(IOErrorEvent.IO_ERROR, function (evt:IOErrorEvent):void { });
198                        }
199                        message.text = "データ取得開始……";
200                        wassr.getFeed(displayFeed);
201                        wassr.getReplies(displayReplies);
202                }
203               
204                public function get_channel_list():void
205                {
206                        if (!wassr) {
207                                wassr = new Wassr(user_id, password, URLRequestDefaults.userAgent);
208                                wassr.addEventListener(IOErrorEvent.IO_ERROR, function (evt:IOErrorEvent):void { });
209                        }
210                        message.text = "チャンネルデータ取得開始……";
211                        wassr.getUserChannelList(function(channels:Array):void{
212                                channelList.dataProvider = channels;
213                                message.text = "";
214                        });
215                }
216               
217                public function timerHandler(evt:TimerEvent):void
218                {
219                        get_feed();
220                }
221               
222                private function displayFeed(feed_item:Object):void
223                {
224                        message.text = "データ取得完了";
225                        feedCanvas.htmlText = makeFeedHTML(feed_item);
226                        message.text = "";
227                }
228               
229                private function displayReplies(feed_item:Object):void
230                {
231                        message.text = "返信データ取得完了";
232                        if ( repliesCanvas ) {
233                                repliesCanvas.htmlText = makeFeedHTML(feed_item);
234                        }
235                        message.text = "";
236                }
237               
238                private function displayChannel(feed_item:Object):void
239                {
240                        message.text = "チャンネルデータ取得完了";
241                        if ( channelCanvas ) {
242                                channelCanvas.htmlText = makeChannelFeedHTML(feed_item);
243                        }
244                        message.text = "";
245                }
246               
247                private function getFeedStyle():String
248                {
249                        var template:Template = new Template();
250                        this.setting.replyFontSize = int(setting.fontSize * 0.9);
251                        return template.process(String(new feedStyleTmpl()), this.setting);
252                }
253               
254                private function makeFeedHTML(feed_item:Object, type:String="feed"):String
255                {
256                        var template:Template = new Template();
257                        var html:String = getFeedStyle();
258                        var pattern:RegExp = /(?<!src=")https?:\/\/[-_.!~*'()\w;\/?:@&=+$,%#]+/g;
259                        html += "<table>";
260                        for (var j:int=0; j<20; j++) {
261                                if (feed_item[j]) {
262                                        var vars:Object = feed_item[j];
263                                        if (feed_item[j].reply_message) {
264                                                vars.reply_message = feed_item[j].reply_message.replace(pattern, "[URL]");
265                                        }
266                                        vars.html = feed_item[j].html.replace(pattern, "<a href=\"$&\" target=\"_blank\">[URL]</a>");
267                                        vars.profile_url = feed_item[j].user.profile_image_url;
268                                        vars.user_screen_name = feed_item[j].user.screen_name;
269                                        var fmt:DateFormatter = new DateFormatter();
270                                        fmt.formatString = "YYYY/MM/DD JJ:NN";
271                                        vars.time = fmt.format(new Date(int(feed_item[j].epoch) * 1000));
272                                        if (feed_item[j].user.protected) {
273                                                vars.iine_icon = "app:/assets/secret.png";
274                                        } else {
275                                                if ( iine_map[feed_item[j].rid] == 1 ) {
276                                                        vars.iine_icon = "app:/assets/good.png";
277                                                } else {
278                                                        vars.iine_icon = "app:/assets/normal.png";
279                                                }
280                                        }
281                                        html += template.process(String(new feedTmpl()), vars);
282                                }
283                        }
284                        trace(html);
285                        return html + "</table>";
286                }
287
288                private function makeChannelFeedHTML(feed_item:Object):String
289                {
290                        var template:Template = new Template();
291                        var html:String = getFeedStyle();
292                        var pattern:RegExp = /(?<!src=")https?:\/\/[-_.!~*'()\w;\/?:@&=+$,%#]+/g;
293                        html += "<table>";
294                        for (var j:int=0; j<20; j++) {
295                                if (feed_item[j]) {
296                                        var vars:Object = feed_item[j];
297                                        vars.html = feed_item[j].body.replace(pattern, "<a href=\"$&\" target=\"_blank\">[URL]</a>");
298                                        vars.profile_url = feed_item[j].user.profile_image_url;
299                                        vars.user_nick = feed_item[j].user.nick;
300                                        var fmt:DateFormatter = new DateFormatter();
301                                        fmt.formatString = "YYYY/MM/DD JJ:NN";
302                                        vars.time = fmt.format(new Date(int(feed_item[j].epoch) * 1000));
303                                        vars.favorites = vars.favorites.map(function(item:Object, idx:Number, array:Array):Object {
304                                                return "<a href=\"http://wassr.jp/user/"+item+"\"><img src=\"app:/assets/good.png\" /></a>";
305                                        });
306                                        html += template.process(String(new feedChannelTmpl()), vars);
307                                }
308                        }
309                        trace(html);
310                        return html + "</table>";
311                }
312               
313                private function displayParentComment(evt:Event):void
314                {
315                        Alert.show(evt.currentTarget.data);
316                }
317
318                public function applicationDragHandler(event:MouseEvent):void
319                {
320                        stage.nativeWindow.startMove();
321                }
322                   
323                private function onClose(evt:MouseEvent):void
324                {
325                        stage.nativeWindow.close();
326                }
327               
328                private function onMinimize(evt:MouseEvent):void
329                {
330                        stage.nativeWindow.minimize();
331                }
332               
333                private function showPictWindow(evt:MouseEvent):void
334                {
335                        var pict:pictWindow = pictWindow(
336                                PopUpManager.createPopUp(this, pictWindow, true)
337                        );
338                        pict.load(stat);
339                        PopUpManager.centerPopUp(pict);
340                }
341
342                public function statusUpdate(res_rid:String=null):void
343                {
344                        if ( tabNavi.selectedIndex == 2 ) {
345                                var channel:String = channelList.selectedItem.name_en;
346                                if (stat.text == "") {
347                                        wassr.getChannelFeed(channel, displayChannel);
348                                        return;
349                                }
350                                wassr.channelStatusUpdate(channel, stat.text, function ():void {
351                                        wassr.getChannelFeed(channel, displayChannel);
352                                });
353                        } else {
354                                if (stat.text == "") {
355                                        get_feed();
356                                        return;
357                                }
358                                wassr.statusUpdate(stat.text, function ():void {get_feed();}, res_rid);
359                        }
360                        stat.text = "";
361                }
362               
363                private function selectChannel():void
364                {
365                        channelImage.source = channelList.selectedItem.image_url;
366                        wassr.getChannelFeed(channelList.selectedItem.name_en, displayChannel);
367                }
368               
369                public function startResize(event:MouseEvent):void
370                {
371                        stage.nativeWindow.startResize(NativeWindowResize.BOTTOM_RIGHT);
372                }
373               
374                public function onResize(event:Event):void
375                {
376                        this.height = stage.nativeWindow.height;
377                        this.width = stage.nativeWindow.width;
378                        this.panel.height = stage.nativeWindow.height;
379                        this.panel.width = stage.nativeWindow.width;
380                        this.ControlArea.width = this.panel.width - 20;
381                        this.tabNavi.width = this.panel.width - 20;
382                        this.tabNavi.height = this.height - 120;
383                        this.stat.width = this.width - 115;
384                        this.message.width = this.width - 200;
385                }
386               
387                public function alwaysFront(event:Event):void
388                {
389                        if (this.alwaysFrontChk.selected == true) {
390                                stage.nativeWindow.alwaysInFront = true;
391                        } else {
392                                stage.nativeWindow.alwaysInFront = false;
393                        }
394                }
395               
396                private function saveWindowSize(event:Event):void
397                {
398                        saveSetting("windowWidth", stage.nativeWindow.width);
399                        saveSetting("windowHeight", stage.nativeWindow.height);
400                }
401
402                private function savePosition(event:MouseEvent):void {
403                        if ( this.panel.contains(event.target as DisplayObject) ) return;
404                        saveSetting("windowX", stage.nativeWindow.x);
405                        saveSetting("windowY", stage.nativeWindow.y);
406                }
407
408                public function settingTab():void {
409                        bcolorSel.selectedColor = panel.getStyle("backgroundColor");
410                        alphaSel.value = panel.getStyle("backgroundAlpha");
411                        fcolorSel.selectedColor = setting.fontColor;
412                        fsizeSel.value = setting.fontSize;
413                        label1.setStyle("color", fcolorSel.selectedColor);
414                        label2.setStyle("color", fcolorSel.selectedColor);
415                        label3.setStyle("color", fcolorSel.selectedColor);
416                        label4.setStyle("color", fcolorSel.selectedColor);
417                }
418
419                private function doSetting():void
420                {
421                        saveSetting("backColor", bcolorSel.selectedColor);
422                        saveSetting("backAlpha", alphaSel.value);
423                        saveSetting("fontColor", fcolorSel.selectedColor);
424                        saveSetting("fontSize", fsizeSel.value);
425                        setting.fontColor = fcolorSel.selectedColor.toString(16);
426                        setting.fontSize = fsizeSel.value;
427                        panel.setStyle("backgroundColor", bcolorSel.selectedColor);
428                        panel.setStyle("color", fcolorSel.selectedColor);
429                        alwaysFrontChk.setStyle("color", fcolorSel.selectedColor);
430                        message.setStyle("color", fcolorSel.selectedColor);
431                        label1.setStyle("color", fcolorSel.selectedColor);
432                        label2.setStyle("color", fcolorSel.selectedColor);
433                        label3.setStyle("color", fcolorSel.selectedColor);
434                        label4.setStyle("color", fcolorSel.selectedColor);
435                        panel.setStyle("backgroundAlpha", alphaSel.value);
436                        get_feed();
437                }
438               
439                private function version():String
440                {
441                        default xml namespace = new Namespace('http://ns.adobe.com/air/application/1.1');
442                        return NativeApplication.nativeApplication.applicationDescriptor.version;
443                }
444               
445                private function updateCheck():void
446                {
447                        var versionLoader:URLLoader = new URLLoader();
448                        versionLoader.addEventListener(Event.COMPLETE, function (evt:Event):void {
449                                verXML = new XML(evt.target.data);
450                                var localVer:String = version();
451                                var remoteVer:String = verXML.version;
452                                if ( remoteVer != localVer ) {
453                                        Alert.show("新しいwasacoがリリースされています。\n" +
454                                                   "更新しますか?\n\n" +
455                                                   "現在のバージョン:" + localVer + "\n" +
456                                                   "新しいバージョン:" + remoteVer,
457                                                   "確認", Alert.YES | Alert.NO, null, updateConfirm);
458                                } else {
459                                        Alert.show("ご利用のwasacoは最新版です。", "確認", Alert.OK, null, null);
460                                }
461                        });
462                        versionLoader.load(new URLRequest("http://fushihara.net/wasaco/version.xml"));
463                }
464               
465                private function updateConfirm(evt:CloseEvent): void
466                {
467                        if (evt.detail == Alert.YES) {
468                                var archiveLoader:URLLoader = new URLLoader();
469                                archiveLoader.dataFormat = URLLoaderDataFormat.BINARY;
470                                archiveLoader.addEventListener(Event.COMPLETE, function (evt:Event):void {
471                                        var airFile:File = File.createTempFile();
472                                        var fs:FileStream = new FileStream();
473                                        var data:ByteArray = evt.target.data as ByteArray;
474                                        fs.open(airFile, FileMode.WRITE);
475                                        fs.writeBytes(data);
476                                        fs.close();
477                                       
478                                        var updater:Updater = new Updater();
479                                        updater.update(airFile, verXML.version);
480                                });
481                                archiveLoader.load(new URLRequest(verXML.archive));
482                                updateProgress.source = archiveLoader;
483                                updateProgress.visible = true;
484                        }
485                }
486
487        ]]>
488        </mx:Script>
489        <mx:Style>
490                Application {
491                        background-image: "";
492                        background-color: "";
493                        background-alpha: 0;
494                }
495                Panel {
496                        color: #ffffff;
497                        borderStyle: solid;
498                        roundedBottomCorners: true;
499                        cornerRadius: 15;
500                        shadowDirection: right;
501                        backgroundColor: #000000;
502                        backgroundAlpha: 0.8;
503                        width: 400px;
504                        height: 500px;
505                }
506        </mx:Style>
507        <mx:Panel id="panel" x="0" y="0" title="wasaco" titleIcon="@Embed(source='assets/wasaco.png')" width="374">
508                <mx:Canvas x="0" y="0" width="100%" height="45" id="ControlArea">
509                        <mx:TextInput x="10" y="10" width="254" id="stat" color="#111111" enter="statusUpdate();"  height="22"/>
510                        <mx:Button right="60" y="10" width="22" click="showPictWindow(event);" icon="@Embed('assets/heart.png')" fontSize="9" toolTip="絵文字入力"/>
511                        <mx:Button right="35" y="10" click="statusUpdate();" width="22" icon="@Embed('assets/action_refresh_blue.gif')" fontSize="9" toolTip="ヒトコト投稿/更新"/>
512                        <mx:Image id="minimizeBtn" source="assets/minimize_icon.png" width="16" height="16" right="16" y="0"/>
513                        <mx:Image id="closeBtn" source="assets/close_icon.png" width="16" height="16" right="0" y="0"/>
514                </mx:Canvas>
515                <mx:TabNavigator id="tabNavi" width="100%" height="380" color="#000000" backgroundAlpha="0.0">
516                        <mx:Canvas label="Timeline">
517                                <mx:HTML x="0" y="0" width="100%" height="100%" id="feedCanvas" backgroundAlpha="0.0" />
518                        </mx:Canvas>
519                        <mx:Canvas label="replies" width="100%" height="100%" backgroundAlpha="0.0">
520                                <mx:HTML x="0" y="0" width="100%" height="100%" id="repliesCanvas" backgroundAlpha="0.0" creationComplete="initReplies()" />
521                        </mx:Canvas>
522                        <mx:Canvas label="channel" width="100%" height="100%" backgroundAlpha="0.0">
523                                <mx:ComboBox x="10" y="10" width="257" id="channelList" labelField="title" change="selectChannel()"></mx:ComboBox>
524                                <mx:HTML x="0" y="100" width="100%" height="100%" id="channelCanvas" backgroundAlpha="0.0" creationComplete="initChannel()" />
525                                <mx:Image x="275" y="10" id="channelImage"/>
526                        </mx:Canvas>
527                        <mx:Canvas label="Setting" width="100%" height="100%" color="#010101" creationComplete="settingTab()">
528                                <mx:Label id="label1" x="14" y="10" text="背景色"  color="#FEFEFE"/>
529                                <mx:ColorPicker x="27" y="36" id="bcolorSel" selectedColor="#277100"/>
530                                <mx:Label id="label2" x="96.5" y="10" text="透過度"  color="#FEFEFE"/>
531                                <mx:HSlider x="94" y="39" width="121" id="alphaSel" minimum="0" maximum="1" snapInterval="0.01"/>
532                                <mx:Button x="10" y="209" label="設定する" width="99" id="okBtn" click="doSetting()" />
533                                <mx:Button x="10" y="252" label="アップデートチェック" width="122" click="updateCheck()" />
534                                <mx:ProgressBar x="141" y="263" height="11" id="updateProgress" visible="false"/>
535                                <mx:Label id="label3" x="14" y="76" text="文字色"  color="#FEFEFE"/>
536                                <mx:ColorPicker x="27" y="102" id="fcolorSel" selectedColor="#277100"/>
537                                <mx:Label id="label4" x="96.5" y="77" text="文字のサイズ"  color="#FEFEFE"/>
538                                <mx:HSlider x="94" y="106" width="121" id="fsizeSel" minimum="8" maximum="40" snapInterval="1"/>
539                        </mx:Canvas>
540                </mx:TabNavigator>
541                <mx:Canvas bottom="0" width="100%" height="20" color="#ffffff" id="statusBar" backgroundAlpha="0.0">
542                        <mx:Image id="resizeBtn" source="assets/resize_icon.png" width="16" height="16" right="0" bottom="0" />
543                        <mx:CheckBox id="alwaysFrontChk" x="0" y="0" label="常に最前面に表示する" click="alwaysFront(event)" />
544                        <mx:Label id="message" x="130" width="200" height="20"  y="2"/>
545                </mx:Canvas>
546        </mx:Panel>
547</mx:Application>
Note: See TracBrowser for help on using the browser.