--- /dev/null
+package library {
+
+public class DateLibrary {
+ /* 文字列を日付型に変更する */
+ public static function parseDate(value:String) :String {
+ //2008-07-09T16:20:48Z to
+ //YYYY/MM/DD HH:MM:SS TZD
+ //trace(value);
+ var patternStr:String = "(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}:\\d{2}):\\d{2}Z";
+ var pattern:RegExp = new RegExp(patternStr, "i") ;
+ var rep:String = value.replace(pattern, "$2/$3 $4");
+ return rep;
+ }
+
+}}
\ No newline at end of file
--- /dev/null
+package library {
+
+import model.*;
+import mx.collections.ArrayCollection;
+import flash.display.Bitmap;
+
+/* ユーザ情報を取得するHelper */
+public class FriendsHelper {
+
+private static var instance:FriendsHelper = new FriendsHelper();
+
+[Bindable]
+public var friends:Object;
+[Bindable]
+public var friendsArray:ArrayCollection;
+[Bindable]
+public var feedRequestArray:ArrayCollection;
+
+public function FriendsHelper() {
+ friends = new Object();
+ friendsArray = new ArrayCollection();
+ feedRequestArray = new ArrayCollection();
+
+ feedRequestArray.addItem(new HomeModel());
+ feedRequestArray.addItem(new UserFriendsModel());
+
+}
+
+public static function getFeedRequestArray():ArrayCollection {
+ return instance.feedRequestArray;
+}
+
+public static function getFriendArray():ArrayCollection {
+ return instance.friendsArray;
+}
+
+// *************************************
+
+public static function getFriendImage(nickname:String):Bitmap {
+ var bitmap:Bitmap = instance.friends[nickname].iconImage;
+ return bitmap;
+}
+
+public static function getFriend(nickName:String):FriendModel {
+ return instance.friends[nickName];
+}
+
+public static function getFriendXML(xml:XML):FriendModel {
+ var friend:FriendModel = instance.friends[xml.nickName];
+ if (friend != null) {
+ return friend;
+ } else {
+ return addFriendXML(xml);
+ }
+}
+
+// ********************************************
+
+public static function addFriend(friend:FriendModel):FriendModel {
+ instance.friends[friend.nickname] = friend;
+ instance.friendsArray.addItem(friend);
+ instance.feedRequestArray.addItem(friend);
+ return friend;
+}
+
+
+public static function addFriendXML(xml:XML, isMyEntry:Boolean = false):FriendModel {
+ if (instance.friends[xml.nickname] == null) {
+ var friend:FriendModel = new FriendModel(xml, isMyEntry);
+ return addFriend(friend);
+ } else {
+ return instance.friends[xml.nickname];
+ }
+}
+
+public static function addFriendListXML(xml:XML):void {
+ instance.feedRequestArray.addItem(new FriendListModel(xml));
+}
+
+
+}
+}
\ No newline at end of file
--- /dev/null
+package library {
+
+import mx.controls.Image;
+import flash.display.Bitmap;
+import flash.display.BitmapData;
+import flash.utils.getTimer;
+import flash.utils.Dictionary;
+import flash.events.Event;
+import flash.display.Loader;
+import flash.net.URLRequest;
+
+
+public class ImageLibrary {
+
+//static private const MESSAGE_DEFAULT:String = "[image status]";
+[Bindable ("readonly")]
+static private var imageCache:Dictionary = new Dictionary();
+
+
+// /**
+// * 画像読み込み完了時のハンドル
+// * @param event
+// */
+// public static function onImageComplete(event:Event):BitmapData{
+// var img:Image = event.target as Image;
+// return saveImage(img);
+// }
+
+ public static function saveImage(image:Image):BitmapData{
+ // 画像のキャッシュが履歴になければ保存する
+ if (! imageCache[image.source]){
+ // 画像をBitmapData化
+ var bmpData:BitmapData = new BitmapData
+ (image.content.width, image.content.height, true);
+ //キャッシュデータに保存
+ imageCache[image.source] = bmpData;
+ bmpData.draw(image.content);
+ }
+ return imageCache[image.source];
+ }
+
+ public static function saveBitMap(path:String, bmpData:Bitmap):Bitmap{
+ // 画像のキャッシュが履歴になければ保存する
+ if (! imageCache[path]){
+ //キャッシュデータに保存
+ imageCache[path] = bmpData;
+ }
+ return imageCache[path];
+ }
+
+
+ public static function loadBitmap(url:String, callBack:Function):void {
+ var imageLoader:Loader = new Loader();
+ var imageRequest:URLRequest = new URLRequest(url);
+
+ imageLoader.load(imageRequest);
+ imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
+ function my(event:Event):void {
+ callBack(saveBitMap(url, event.target.content));
+ imageLoader.removeEventListener(Event.COMPLETE, my);
+ });
+ }
+
+
+
+
+}
+}
\ No newline at end of file
--- /dev/null
+package library {
+
+import model.ServiceModel;
+import service.FriendFeedService;
+
+import mx.collections.ArrayCollection;
+import mx.rpc.events.ResultEvent;
+import flash.display.Bitmap;
+
+/* Service情報を取得するHelper */
+public class ServicesHelper {
+
+private static var instance:ServicesHelper = new ServicesHelper();
+
+[Bindable]
+public var services:Object;
+[Bindable]
+public var servicesArray:ArrayCollection;
+
+public function ServicesHelper() {
+ services = new Object();
+ servicesArray = new ArrayCollection();
+ FriendFeedService.getServiceList(getServiceCallBack);
+}
+
+/* Serviceの結果が帰って来たとき */
+private function getServiceCallBack(event:ResultEvent):void {
+ servicesArray.addItem(new ServiceModel(null));
+ for each(var f:XML in event.result.service) {
+ var feed:ServiceModel = new ServiceModel(f);
+ services[f.id] = feed;
+ servicesArray.addItem(feed);
+ }
+}
+
+public static function getServiceArray():ArrayCollection {
+ return instance.servicesArray;
+}
+
+public static function getIconImage(id:String):Bitmap {
+ var bitmap:Bitmap = instance.services[id].iconImage;
+ if (bitmap != null) {
+ return new Bitmap(bitmap.bitmapData.clone());
+ } else {
+ return null;
+ }
+}
+
+public static function getService(id:String):ServiceModel {
+ return instance.services[id];
+}
+
+
+
+
+}
+}
\ No newline at end of file
--- /dev/null
+\r
+import service.FriendFeedService;\r
+import mx.rpc.events.ResultEvent;\r
+import mx.collections.ArrayCollection;\r
+import mx.managers.PopUpManager;\r
+import mx.managers.PopUpManagerChildList;\r
+\r
+import model.*;\r
+import library.*;\r
+\r
+[Bindable]\r
+public static var SETTING:SettingModel = new SettingModel();\r
+\r
+\r
+\r
+[Bindable]\r
+public var feedsArray:FeedsModel;\r
+\r
+\r
+\r
+/* 初期化が完了したとき */\r
+public function onInitialize():void {\r
+ feedsArray = new FeedsModel();\r
+}\r
+\r
+/* Windowの作成が完了したとき */\r
+public function onWindowCompleted():void {\r
+ if (SETTING.nickName == null || SETTING.nickName.length == 0) {\r
+ showLoginDialog();\r
+ } else {\r
+ dataInitialize();\r
+ }\r
+ addEventListener(KeyboardEvent.KEY_DOWN, \r
+ function(e:KeyboardEvent):void {\r
+ if (e.keyCode == Keyboard.MINUS && e.ctrlKey) {\r
+ onFontDown();\r
+ } else if (e.keyCode == Keyboard.SEMICOLON && e.ctrlKey) {\r
+ onFontUp();\r
+ } else if (e.keyCode == Keyboard.F5) {\r
+ refreshClicked();\r
+ }\r
+ });\r
+ friendEntryList.setFocus();\r
+}\r
+\r
+/* 表示データを初期化する */\r
+public function dataInitialize():void {\r
+ refreshClicked();\r
+ FriendFeedService.getUserProfile(SETTING.nickName, getUserProfileCallBack);\r
+ cmbService.selectedIndex = 0;\r
+\r
+}\r
+\r
+/*\r
+ * UserProfileの結果が帰って来たとき\r
+ * @param event ResultEvent\r
+ */\r
+private function getUserProfileCallBack(event:ResultEvent):void {\r
+ var feedXml:XML = event.result as XML;\r
+ for each(var x:XML in feedXml.list) {\r
+ FriendsHelper.addFriendListXML(x);\r
+ }\r
+ FriendsHelper.addFriendXML(feedXml, true);\r
+ for each(var f:XML in feedXml.subscription) {\r
+ FriendsHelper.addFriendXML(f);\r
+ }\r
+\r
+}\r
+\r
+/* Refreshボタンを押されたとき */\r
+public function refreshClicked():void {\r
+ FriendFeedService.getFriendsEntries(getFeedUrl(), getServiceId(), getEntriesCallBack);\r
+}\r
+\r
+private function getServiceId():String {\r
+ if (cmbService.selectedItem == null) {\r
+ return null;\r
+ } else {\r
+ return cmbService.selectedItem.id;\r
+ }\r
+}\r
+\r
+private function getFeedUrl():String {\r
+ if (cmbFriend.selectedItem == null) {\r
+ return null;\r
+ } else {\r
+ return cmbFriend.selectedItem.requestUrl;\r
+ }\r
+}\r
+/* Entryの結果が返ってきたとき */\r
+private function getEntriesCallBack(event:ResultEvent):void {\r
+ feedsArray.removeAll();\r
+ for each(var f:XML in event.result.entry) {\r
+ var feed:FeedModel = new FeedModel(f);\r
+ feedsArray.addItem(feed);\r
+ }\r
+}\r
+\r
+/* ログインダイアログを表示する */\r
+public function showLoginDialog():void {\r
+ var login:LoginDialog = LoginDialog(\r
+ PopUpManager.createPopUp(this, LoginDialog , false, PopUpManagerChildList.POPUP));\r
+ login.setCallBackFunction(onLoginAuth);\r
+ PopUpManager.centerPopUp(login);\r
+ login.y = 50;\r
+}\r
+\r
+/* ログイン情報を保持してサービスの一覧を取得する */\r
+private function onLoginAuth(nickName:String, remoteKey:String):void {\r
+ SETTING.nickName = nickName;\r
+ SETTING.remoteKey = remoteKey;\r
+ dataInitialize();\r
+ //FriendFeedService.getServiceList(onServiceListCallBack);\r
+}\r
+\r
+\r
+\r
+/* フォントの拡大(+)が押された時 */\r
+protected function onFontUp():void {\r
+ var size:int = AFriendFeed.SETTING.fontSize;\r
+ AFriendFeed.SETTING.fontSize = size + 1;\r
+}\r
+\r
+/* フォントの縮小(-)が押された時 */\r
+protected function onFontDown():void {\r
+ var size:int = AFriendFeed.SETTING.fontSize;\r
+ if (size <= 1 ) {\r
+ return;\r
+ } \r
+ AFriendFeed.SETTING.fontSize = size - 1;\r
+}\r
+\r
+/* homeボタンが押された時 */\r
+protected function onHome():void {\r
+ \r
+}\r
+\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<mx:WindowedApplication title="AFriendFeed" windowComplete="onWindowCompleted()" backgroundAlpha="0.5" layout="absolute" backgroundColor="#ffffff" showStatusBar="false" initialize="onInitialize()" xmlns:mx="http://www.adobe.com/2006/mxml" height="600" width="400">
+<mx:Script source="AFriendFeed.as"/>
+<mx:ApplicationControlBar horizontalGap="1" verticalGap="2" width="100%">
+<mx:Spacer width="100%"/>
+<mx:ComboBox selectedIndex="0" itemRenderer="renderer.FriendRenderer" labelField="renderName" toolTip="User" dataProvider="{FriendsHelper.getFeedRequestArray()}" id="cmbFriend" change="refreshClicked()" y="0" x="60" height="20" width="120"/>
+<mx:ComboBox itemRenderer="renderer.ServiceRenderer" toolTip="Service" dataProvider="{ServicesHelper.getServiceArray()}" id="cmbService" change="refreshClicked()" y="0" x="60" height="20" width="120"/>
+<mx:Button paddingLeft="0" click="refreshClicked()" toolTip="Refresh (F5)" paddingRight="0" icon="@Embed('icons/arrow_refresh_small.png')" y="0" x="0" height="20" width="20"/>
+<mx:Button leading="0" label="+" paddingLeft="0" click="onFontUp()" toolTip="FontSize Up (Command +)" paddingRight="0" y="10" x="80" height="20" width="20"/>
+<mx:Button label="-" paddingLeft="0" click="onFontDown()" toolTip="FontSize Down (Command -)" paddingRight="0" y="10" x="100" height="20" width="20"/>
+<mx:Button paddingLeft="0" click="showLoginDialog()" toolTip="Login" paddingRight="0" icon="@Embed('icons/user.png')" y="0" x="0" height="20" width="20"/>
+</mx:ApplicationControlBar>
+<mx:VBox backgroundColor="#ffffff" alpha="0.7" y="30" height="100%" width="100%">
+<mx:List itemRenderer="MainListItemRenderer" wordWrap="true" alternatingItemColors="[#FFFFFF, #DDFF2FE]" variableRowHeight="true" id="friendEntryList" dataProvider="{feedsArray}" y="0" x="0" height="100%" width="100%"/>
+</mx:VBox>
+</mx:WindowedApplication>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%">
+<mx:Image source="@Embed('icons/comment.png')"/>
+<mx:Text id="comment" fontSize="{AFriendFeed.SETTING.commentFontSize}" htmlText="{data.htmlString}" text="comment" width="100%"/>
+</mx:HBox>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%">
+<mx:Image source="@Embed('icons/emoticon_smile.png')"/>
+<mx:Text id="comment" fontSize="{AFriendFeed.SETTING.commentFontSize}" htmlText="{data.htmlString}" width="100%"/>
+</mx:HBox>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<mx:TitleWindow layout="absolute" title="Login" borderAlpha="0.8" xmlns:mx="http://www.adobe.com/2006/mxml" borderColor="#DDFF2FE">
+<mx:Script source="LoginDialogScript.as"/>
+<mx:VBox paddingBottom="3" paddingTop="3" width="350">
+<mx:HBox width="100%">
+<mx:Label fontSize="14" text="NickName" width="120"/>
+<mx:TextInput fontSize="14" text="{AFriendFeed.SETTING.nickName}" id="txtNickName" width="100%"/>
+</mx:HBox>
+<mx:HBox width="100%">
+<mx:Label fontSize="14" text="RemoteKey" width="120"/>
+<mx:TextInput fontSize="14" text="{AFriendFeed.SETTING.remoteKey}" id="txtRemoteKey" width="100%"/>
+</mx:HBox>
+</mx:VBox>
+<mx:ControlBar y="60" x="0">
+<mx:Button label="OK" fontSize="14" click="onOk()" width="100"/>
+<mx:Button label="CANCEL" fontSize="14" click="onCancel()" width="100"/>
+</mx:ControlBar>
+</mx:TitleWindow>
--- /dev/null
+import mx.managers.PopUpManager;
+
+private var callback:Function;
+
+/*
+ * CallBackするFuncitonを設定する。
+ * @param call 引数はNickNameとRemoteKeyの2つのString
+ */
+public function setCallBackFunction(call:Function):void {
+ callback = call;
+}
+
+/* OKが押された時 */
+protected function onOk():void {
+ callback(txtNickName.text, txtRemoteKey.text);
+ PopUpManager.removePopUp(this);
+}
+
+/* Cancelが押された時 */
+protected function onCancel():void {
+ PopUpManager.removePopUp(this);
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<mx:HBox verticalScrollPolicy="off" xmlns:mx="http://www.adobe.com/2006/mxml" horizontalGap="2">
+<mx:Script source="MainListItemRendererScript.as"/>
+<mx:VBox>
+<mx:Image toolTip="{data.serviceName}" source="{data.serviceImage}" height="20" width="20"/>
+<mx:Image complete="data.onImageComplete(event)" toolTip="{data.userTooltip}" source="{data.userImage}" height="20" width="20"/>
+</mx:VBox>
+<mx:VBox verticalGap="0" width="100%">
+<mx:HBox verticalScrollPolicy="off" verticalGap="0" width="100%">
+<mx:VBox verticalScrollPolicy="off" verticalGap="0" width="100%">
+<mx:Text fontSize="{AFriendFeed.SETTING.fontSize}" htmlText="{data.titleLink}" text="aaa" width="100%"/>
+<mx:VBox verticalScrollPolicy="off" verticalGap="0" id="contents" color="#336666" width="100%"/>
+</mx:VBox>
+</mx:HBox>
+<mx:HBox verticalGap="0" width="100%">
+<mx:Spacer width="100%"/>
+<mx:Text color="#333333" fontSize="{AFriendFeed.SETTING.commentFontSize}" htmlText="{data.userLink}"/>
+<mx:LinkButton paddingLeft="0" click="onComment()" toolTip="Comment" paddingRight="0" icon="@Embed('icons/comment_add.png')" id="btnComment"/>
+<mx:LinkButton paddingLeft="0" click="onLike()" toolTip="Like" paddingRight="0" icon="@Embed('icons/heart_add.png')" id="btnLike"/>
+<mx:Label textAlign="left" color="#333333" fontSize="{AFriendFeed.SETTING.commentFontSize}" text="{data.updatedString}"/>
+</mx:HBox>
+<mx:HBox visible="false" id="pnlComment" height="0" width="100%">
+<mx:Canvas height="40" y="0" width="10" x="0"/>
+<mx:Image source="@Embed('icons/comment.png')"/>
+<mx:TextArea id="txaComment" y="0" x="20" height="100%" width="100%"/>
+<mx:Button label="add" click="onCommentAdd()" y="0" x="190" height="20" width="50"/>
+</mx:HBox>
+</mx:VBox>
+</mx:HBox>
--- /dev/null
+import service.FriendFeedService;
+import mx.rpc.events.ResultEvent;
+import mx.controls.Alert;
+import model.CommentModel;
+import model.LikeModel;
+
+override public function set data(value:Object) : void{
+ super.data = value;
+ layout();
+ //これをしないと、スクロールしていくとリストの行サイズがおかしくなる
+ validateNow();
+}
+
+private function layout():void {
+ //likeボタンの表示の切替
+ if (btnLike != null && data != null && data.user != null) {
+ if (data.user.isMyEntry) {
+ btnLike.visible = false;
+ } else {
+ btnLike.visible = true;
+ }
+ }
+ //commentの追加
+ contents.removeAllChildren();
+ if (data != null && data.comments != null) {
+ for each(var comment:CommentModel in data.comments) {
+ var render:CommentRenderer = new CommentRenderer();
+ render.data = comment;
+ contents.addChild(render);
+ }
+ }
+ //likeの追加
+ if (data != null && data.likes != null) {
+ for each(var like:LikeModel in data.likes) {
+ var render2:LikeRenderer = new LikeRenderer();
+ render2.data = like;
+ contents.addChild(render2);
+ }
+ }
+}
+
+protected function showURLPage():void {
+ var myURL:URLRequest = new URLRequest(data.link);
+ navigateToURL(myURL,"_blank");
+}
+
+protected function onComment():void {
+ if (pnlComment.visible) {
+ commentUnVisible();
+ } else {
+ pnlComment.visible = true;
+ pnlComment.height = 50;
+ }
+
+}
+
+protected function onCommentAdd():void {
+ FriendFeedService.postComment(data.id, txaComment.text,
+ function(event:ResultEvent):void {
+ commentUnVisible();
+ }
+ );
+}
+
+protected function commentUnVisible():void {
+ pnlComment.visible = false;
+ pnlComment.height = 0;
+}
+
+protected function onLike():void {
+ FriendFeedService.postLike(data.id, callBack);
+}
+
+protected function callBack(event:ResultEvent):void {
+ trace(event.toString());
+}
\ No newline at end of file
--- /dev/null
+package model {
+
+import library.DateLibrary;
+import service.FriendFeedService;
+
+
+
+public class CommentModel {
+
+[Bindable]
+protected var _xml:XML;
+
+
+public function CommentModel(xml:XML) {
+ _xml = xml;
+}
+
+[Bindable ("readonly")]
+public function get date():String {
+ return _xml.date;
+}
+
+[Bindable ("readonly")]
+public function get id():String {
+ return _xml.id;
+}
+
+[Bindable ("readonly")]
+public function get htmlString():String {
+ return _xml.body
+ + ' by <a href=\"' + _xml.user.profileUrl + "\">" + _xml.user.nickname + "</a>";
+}
+
+public function toString():String {
+ return _xml.user.nickname + " like";
+}
+
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+
+import library.FriendsHelper;
+import library.ServicesHelper;
+import library.DateLibrary;
+import mx.collections.ArrayCollection;
+import model.CommentModel;
+import model.LikeModel;
+
+public class FeedModel {
+
+ [Bindable]
+ private var _feedXML:XML;
+
+ [Bindable]
+ private var _service:ServiceModel;
+
+ [Bindable]
+ private var _likes:ArrayCollection;
+
+ [Bindable]
+ private var _comments:ArrayCollection;
+
+
+
+ public function FeedModel(feedXML:XML) {
+ _feedXML = feedXML;
+ _service = ServicesHelper.getService(feedXML.service.id);
+ _comments = new ArrayCollection();
+ _likes = new ArrayCollection();
+ addComments();
+ addLikes();
+ }
+
+ private function addComments():void {
+ for each (var comment:XML in _feedXML.comment) {
+ _comments.addItem(new CommentModel(comment));
+ }
+ }
+
+ private function addLikes():void {
+ for each (var like:XML in _feedXML.like) {
+ _likes.addItem(new LikeModel(like));
+ }
+ }
+
+ [Bindable ("readonly")]
+ public function get title():String {
+ return _feedXML.title;
+ }
+
+
+ [Bindable ("readonly")]
+ public function get titleLink():String {
+ return "<a href=\"" + link + "\">" + title + "</a>";
+ }
+
+ [Bindable ("readonly")]
+ public function get updatedString():String {
+ return DateLibrary.parseDate(_feedXML.updated);
+ }
+
+ [Bindable ("readonly")]
+ public function get comments():ArrayCollection {
+ return _comments;
+ }
+
+ [Bindable ("readonly")]
+ public function get likes():ArrayCollection {
+ return _likes;
+ }
+
+// [Bindable ("readonly")]
+// public function get commentHtmlString():String {
+// var comments:Object = _feedXML.comment;
+// if (comments[0] is XML) {
+// var arrayString:String = '';
+// for each (var comment:Object in comments) {
+// arrayString = arrayString
+// + getCommentFormatString(comment) + "<br>";
+// }
+// return arrayString;
+//
+// } else {
+// return getCommentFormatString(comments);
+//
+// }
+// }
+//
+// protected function getCommentFormatString(comment:Object):String {
+// if (new String(comment.body) == ''){
+// return '';
+// } else {
+// return comment.body
+// + ' by <a href=\"' + comment.user.profileUrl + "\">" + comment.user.nickname + "</a>"
+// + " (" + parseDate(comment.date) + ")";
+// }
+// }
+
+
+ [Bindable ("readonly")]
+ public function get link():String {
+ return _feedXML.link;
+ }
+
+ [Bindable ("readonly")]
+ public function get serviceImage():Object {
+ return _service.iconImage;
+ }
+
+ [Bindable ("readonly")]
+ public function get serviceName():Object {
+ return _service.name;
+ }
+
+// [Bindable ("readonly")]
+// public function get commentImage():Object {
+// var value:String = commentHtmlString;
+// if (value != null && value.length > 0) {
+// return imgComment;
+// } else {
+// return null;
+// }
+// }
+
+ [Bindable ("readonly")]
+ public function get userLink():String {
+ return "<a href=\"" + _feedXML.user.profileUrl + "\">" +
+ _feedXML.user.nickname + " / " + _feedXML.user.name + "</a>";
+ }
+
+
+ [Bindable ("readonly")]
+ public function get userImage():Object {
+ return FriendsHelper.getFriendImage(_feedXML.user.nickname);
+ }
+
+ [Bindable ("readonly")]
+ public function get user():FriendModel {
+ return FriendsHelper.getFriend(_feedXML.user.nickname);
+ }
+
+ [Bindable ("readonly")]
+ public function get userTooltip():String {
+ return _feedXML.user.nickname + " / " + _feedXML.user.name;
+ }
+
+ [Bindable ("readonly")]
+ public function get id():String {
+ return _feedXML.id;
+ }
+
+// public function toString():String {
+// return titleLink + "<BR>" + commentHtmlString + "<BR>" + userLink;
+// }
+//
+// /* 文字列を日付型に変更する */
+// private function parseDate(value:String) :String {
+// //2008-07-09T16:20:48Z to
+// //YYYY/MM/DD HH:MM:SS TZD
+// var patternStr:String = "(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}:\\d{2}):\\d{2}Z";
+// var pattern:RegExp = new RegExp(patternStr, "i") ;
+// var rep:String = value.replace(pattern, "$2/$3 $4");
+// return rep;
+// }
+
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+
+import mx.collections.ArrayCollection;
+
+public class FeedsModel extends ArrayCollection {
+
+[Bindable]
+public var startIndex:int;
+
+
+
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+
+import library.ImageLibrary;
+import flash.display.Bitmap;
+import service.FriendFeedService;
+import flash.display.Bitmap;
+
+
+public class FriendListModel implements IFeedRequest {
+
+[Bindable]
+protected var _xml:XML;
+
+[Bindable]
+[Embed(source='../icons/group_link.png')]
+protected var _iconImage:Class;
+
+public function FriendListModel(xml:XML) {
+ _xml = xml;
+}
+
+// implements IFeedRequest
+// ******************************************
+[Bindable ("readonly")]
+public function get requestUrl():String {
+ return "list/" + nickname;
+}
+
+[Bindable ("readonly")]
+public function get renderImage():Object {
+ return _iconImage;
+}
+
+[Bindable ("readonly")]
+public function get renderName():String {
+ return nickname;
+}
+
+// ******************************************
+
+[Bindable ("readonly")]
+public function get id():String {
+ return _xml.id;
+}
+
+[Bindable ("readonly")]
+public function get name():String {
+ return _xml.name;
+}
+
+[Bindable ("readonly")]
+public function get nickname():String {
+ return _xml.nickname;
+}
+
+
+public function toString():String {
+ return name;
+}
+
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+
+import library.ImageLibrary;
+import flash.display.Bitmap;
+import service.FriendFeedService;
+import flash.display.Bitmap;
+
+
+public class FriendModel implements IFeedRequest {
+
+[Bindable]
+private var _xml:XML;
+
+[Bindable]
+private var _iconImage:Bitmap;
+
+[Bindable]
+private var _isMyEntry:Boolean;
+
+public function FriendModel(xml:XML, isMyEntry:Boolean) {
+ _xml = xml;
+ _isMyEntry = isMyEntry;
+ FriendFeedService.getUserPicture(nickname, function(image:Bitmap):void {
+ iconImage = image;
+ });
+ //ImageLibrary.loadBitmap(_xml.iconUrl, function(image:Bitmap):void { _iconImage = image;});
+}
+
+// implements IFeedRequest
+// ******************************************
+[Bindable ("readonly")]
+public function get requestUrl():String {
+ return "user/" + nickname;
+}
+
+[Bindable ("readonly")]
+public function get renderImage():Object {
+ return iconImage;
+}
+
+[Bindable ("readonly")]
+public function get renderName():String {
+ return nickname;
+}
+
+// ******************************************
+
+[Bindable ("readonly")]
+public function get id():String {
+ return _xml.id;
+}
+
+[Bindable ("readonly")]
+public function get name():String {
+ return _xml.name;
+}
+
+[Bindable ("readonly")]
+public function get nickname():String {
+ return _xml.nickname;
+}
+
+[Bindable ("readonly")]
+public function get profileUrl():String {
+ return _xml.profileUrl;
+}
+
+[Bindable]
+public function get iconImage():Bitmap {
+ if (_iconImage != null) {
+ return new Bitmap(_iconImage.bitmapData.clone());
+ } else {
+ return _iconImage;
+ }
+}
+
+public function set iconImage(image:Bitmap):void {
+ _iconImage = image;
+}
+
+
+[Bindable ("readonly")]
+public function get isMyEntry():Boolean {
+ return _isMyEntry;
+}
+
+
+public function toString():String {
+ return nickname;
+}
+
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+
+public class HomeModel implements IFeedRequest {
+
+[Bindable]
+[Embed(source='../icons/house.png')]
+protected var imgHome:Class
+
+
+// implements IFriendRequest
+// ******************************************
+[Bindable ("readonly")]
+public function get requestUrl():String {
+ return "home";
+}
+
+[Bindable ("readonly")]
+public function get renderImage():Object {
+ return imgHome;
+}
+
+[Bindable ("readonly")]
+public function get renderName():String {
+ return "home";
+}
+
+
+
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+public interface IFeedRequest {
+
+ function get requestUrl():String;
+
+ function get renderImage():Object;
+
+ function get renderName():String;
+}}
\ No newline at end of file
--- /dev/null
+package model {
+
+import library.ImageLibrary;
+import library.FriendsHelper;
+
+import flash.display.Bitmap;
+import service.FriendFeedService;
+import flash.display.Bitmap;
+
+
+public class LikeModel {
+
+[Bindable]
+protected var _xml:XML;
+
+[Bindable]
+protected var _friendModel:FriendModel;
+
+
+public function LikeModel(xml:XML) {
+ _xml = xml;
+ //_friendModel = FriendsHelper.getFriendXML(xml.user);
+}
+
+[Bindable ("readonly")]
+public function get date():String {
+ return _xml.date;
+}
+
+[Bindable ("readonly")]
+public function get user():FriendModel {
+ return _friendModel;
+}
+
+[Bindable ("readonly")]
+public function get htmlString():String {
+ return '<a href=\"' + _xml.user.profileUrl + '\">' + _xml.user.nickname + "</a> like";
+}
+
+
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+
+import library.ImageLibrary;
+import flash.display.Bitmap;
+
+public class ServiceModel {
+
+[Bindable]
+private var _xml:XML;
+
+[Bindable]
+private var _iconImage:Bitmap;
+
+
+public function ServiceModel(xml:XML) {
+ _xml = xml;
+ if (_xml != null) {
+ ImageLibrary.loadBitmap(_xml.iconUrl, function(image:Bitmap):void { iconImage = image;});
+ }
+}
+
+[Bindable ("readonly")]
+public function get id():String {
+ if (_xml == null) {
+ return null;
+ } else {
+ return _xml.id;
+ }
+}
+
+[Bindable ("readonly")]
+public function get name():String {
+ if (_xml == null) {
+ return null;
+ } else {
+ return _xml.name;
+ }
+}
+
+[Bindable ("readonly")]
+public function get url():String {
+ if (_xml == null) {
+ return null;
+ } else {
+ return _xml.url;
+ }
+}
+
+[Bindable]
+public function get iconImage():Bitmap {
+ if (_iconImage == null) {
+ return null;
+ } else {
+ return new Bitmap(_iconImage.bitmapData.clone());
+ }
+}
+
+public function set iconImage(image:Bitmap):void {
+ _iconImage = image;
+}
+
+public function toString():String {
+ return name;
+}
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+ import flash.net.SharedObject;
+
+/*
+ * SharedObjectで保存する内容
+ */
+
+public class SettingModel {
+
+ protected static const SHARED_FILE:String = "AFriendFeed";
+ protected var sharedObject:SharedObject = SharedObject.getLocal(SHARED_FILE);
+ [Bindable]
+ public var serviceSelectedIndex:int;
+ [Bindable]
+ public var serviceLabels:Array = ["", "Twitter", "FriendFeed", "Blog", "Delicious", "YouTube", "Tumblr", "Flickr", "Picasa"];
+ [Bindable]
+ public var services:Array = ["", "twitter", "internal", "blog", "delicious", "youtube", "tumblr", "flickr", "picasa"];
+
+ [Bindable]
+ public function set nickName(nickName:String):void {
+ sharedObject.data.nickName = nickName;
+ sharedObject.flush();
+ }
+
+ public function get nickName():String {
+ return sharedObject.data.nickName;
+ }
+
+ [Bindable]
+ public function set remoteKey(remoteKey:String):void {
+ sharedObject.data.remoteKey = remoteKey;
+ sharedObject.flush();
+ }
+
+ public function get remoteKey():String {
+ return sharedObject.data.remoteKey;
+ }
+
+ [Bindable]
+ public function set fontSize(size:int):void {
+ sharedObject.data.fontsize = size;
+ sharedObject.flush();
+ }
+
+ public function get fontSize():int {
+ if (isNaN(sharedObject.data.fontsize)) {
+ sharedObject.data.fontsize = 13;
+ sharedObject.flush();
+ }
+ return sharedObject.data.fontsize;
+ }
+
+ [Bindable ("readonly")]
+ public function get commentFontSize():int {
+ var s:int = fontSize;
+ if (s <= 2) {
+ return s;
+ } else {
+ return s - 2;
+ }
+ }
+
+
+}
+}
\ No newline at end of file
--- /dev/null
+package model {
+
+
+
+public class UserFriendsModel implements IFeedRequest {
+
+[Bindable]
+[Embed(source='../icons/group.png')]
+protected var imgHome:Class
+
+
+// implements IFriendRequest
+// ******************************************
+[Bindable ("readonly")]
+public function get requestUrl():String {
+ return "user/" + AFriendFeed.SETTING.nickName + "/friends";
+}
+
+[Bindable ("readonly")]
+public function get renderImage():Object {
+ return imgHome;
+}
+
+[Bindable ("readonly")]
+public function get renderName():String {
+ return "my + friends";
+}
+
+
+
+}
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<mx:HBox verticalScrollPolicy="off" xmlns:mx="http://www.adobe.com/2006/mxml" verticalGap="0" horizontalGap="0" fontSize="8" horizontalScrollPolicy="off">
+<mx:Script source="FriendRendererScript.as"/>
+<mx:Image source="{data.renderImage}" height="20"/>
+<mx:Label text="{data.renderName}"/>
+</mx:HBox>
--- /dev/null
+
+
+override public function set data(value:Object) : void{
+ super.data = value;
+ //これをしないと、スクロールしていくとリストの行サイズがおかしくなる
+ validateNow();
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<mx:HBox verticalScrollPolicy="off" xmlns:mx="http://www.adobe.com/2006/mxml" horizontalGap="0" verticalGap="0" fontSize="8" horizontalScrollPolicy="off">
+<mx:Script source="FriendRendererScript.as"/>
+<mx:Image source="{data.iconImage}"/>
+<mx:Label text="{data.name}"/>
+</mx:HBox>
--- /dev/null
+import service.FriendFeedService;
+import mx.rpc.events.ResultEvent;
+import mx.controls.Alert;
+
+override public function set data(value:Object) : void{
+ super.data = value;
+ //これをしないと、スクロールしていくとリストの行サイズがおかしくなる
+ validateNow();
+}
+
+protected function showURLPage():void {
+ var myURL:URLRequest = new URLRequest(data.link);
+ navigateToURL(myURL,"_blank");
+}
+
+protected function onComment():void {
+ //FriendFeedService.postComment
+}
+
+protected function onLike():void {
+ FriendFeedService.postLike(data.id, callBack);
+}
+
+protected function callBack(event:ResultEvent):void {
+ Alert.show(event.toString());
+}
\ No newline at end of file
--- /dev/null
+package service {
+import flash.net.*;
+import flash.events.*;
+import mx.rpc.events.*;
+import mx.rpc.http.mxml.HTTPService;
+import mx.rpc.events.ResultEvent;
+import model.SettingModel;
+import mx.controls.Alert;
+
+import mx.utils.Base64Encoder;
+
+import library.ImageLibrary;
+
+public class FriendFeedService {
+
+ private static const FRIENDFEED_URL:String = "http://friendfeed.com/";
+ private static const FRIENDFEED_FEED_URL:String = FRIENDFEED_URL + "api/feed/";
+ private static const FRIENDFEED_ADD_COMMENT_URL:String = FRIENDFEED_URL + "api/comment";
+ private static const FRIENDFEED_ADD_LIKE_URL:String = FRIENDFEED_URL + "api/like"
+ private static const FRIENDFEED_USER_SERVICES:String = FRIENDFEED_URL + "api/services";
+
+
+
+ public static function getFriendsEntries(url:String, service:String, callback:Function):void {
+ executeFeedService(url, service, callback);
+ }
+
+
+ /** Feedを取得 */
+ private static function executeFeedService(url:String, service:String, callback:Function):void {
+ var url:String = FRIENDFEED_FEED_URL + url + "?format=xml";
+ if (service != null && service != '') {
+ url = url + "&service=" + service ;
+ }
+ httpGetAccess(url, callback);
+ }
+
+ /** CommentをPost */
+ public static function postComment(entry:String, comment:String, callback:Function):void {
+ var httpService:HTTPService = getHttpService();
+ httpService.method = "POST";
+ httpService.url = FRIENDFEED_ADD_COMMENT_URL;
+ httpService.addEventListener(ResultEvent.RESULT,
+ function my(event:ResultEvent):void {
+ callback(event);
+ httpService.removeEventListener(ResultEvent.RESULT, my);
+ });
+ httpService.send({"entry":entry , "body":comment});
+ }
+
+ /** LikeをPost */
+ public static function postLike(entry:String, callback:Function):void {
+ var httpService:HTTPService = getHttpService();
+ httpService.method = "POST";
+ httpService.url = FRIENDFEED_ADD_LIKE_URL;
+ trace(httpService.url);
+ httpService.resultFormat = "object";
+ httpService.addEventListener(ResultEvent.RESULT,
+ function my(event:ResultEvent):void {
+ callback(event);
+ httpService.removeEventListener(ResultEvent.RESULT, my);
+ });
+ httpService.send({"entry":entry});
+ }
+
+ /**
+ * Serviceのリストを取得する
+ *
+ * @param callback コールバックするFunction
+ */
+ public static function getServiceList(callback:Function):void {
+ var url:String = FRIENDFEED_USER_SERVICES + "?format=xml" ;
+ httpGetAccess(url, callback);
+ }
+
+ /** UserProfileを取得する */
+ public static function getUserProfile(nickName:String, callback:Function):void {
+ var url:String = FRIENDFEED_URL + "api/user/" + nickName + "/profile" + "?format=xml";
+ httpGetAccess(url, callback);
+ }
+
+ /** User Pictureを取得する Size can be "small", "medium", or "large". */
+ public static function getUserPicture(nickName:String, callback:Function, size:String="small"):void {
+ var url:String = FRIENDFEED_URL + nickName + "/picture?size=" + size ;
+ ImageLibrary.loadBitmap(url, callback);
+
+ }
+
+ // -------------------------------------------------------------
+
+ /** Serviceのリストを取得する */
+ private static function httpGetAccess(url:String, callback:Function):void {
+ var httpService:HTTPService = getHttpService();
+ httpService.method = "GET";
+ httpService.url = url;
+ httpService.addEventListener(ResultEvent.RESULT,
+ function my(event:ResultEvent):void {
+ callback(event);
+ httpService.removeEventListener(ResultEvent.RESULT, my);
+ });
+ httpService.send();
+ }
+
+ /* HTTPServiceを作成する */
+ private static function getHttpService():HTTPService {
+ var httpService:HTTPService = new HTTPService();
+ httpService.showBusyCursor = true;
+ httpService.useProxy = false;
+ httpService.addEventListener(FaultEvent.FAULT,httpFaultHandler);
+ httpService.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
+ httpService.resultFormat = "e4x";
+ httpService.headers["Content-Type"] = "application/x-www-form-urlencoded";
+
+ //Basic認証用の設定
+ var encoder : Base64Encoder = new mx.utils.Base64Encoder();
+ encoder.encode(AFriendFeed.SETTING.nickName + ":" + AFriendFeed.SETTING.remoteKey);
+ httpService.headers["Authorization"] = "Basic " + encoder.toString();
+
+ return httpService
+ }
+
+ protected static function httpFaultHandler(event:FaultEvent):void {
+ trace('fault\n' + event);
+ }
+
+ protected static function ioErrorHandler(event:IOErrorEvent):void {
+ trace('IOError\n' + event);
+ }
+
+}
+
+}
\ No newline at end of file