マイミクのマイミクまでを含めたマイミク一覧表示してる自作mixiアプリですが、前回から数回ほどちょこちょこと以下の改良を加えました。
- ページオーナーのマイミクやそのマイミクのマイミクに閲覧者本人や閲覧者のマイミクが居た場合に備考を付けるよーにした。
- サーバやブラウザに負荷をなるべくかけないよーにマイミクのマイミク取得はマイミク1人単位で処理するよーにした。
- IE6でも動くよーにした。
まぁ、「IE6対応」と言ってもIE6が対応していないArrayのforEachメソッドを使っちゃってたので、for文に改めただけですが・・・。(^^;A
で、コードは↓こんな感じです。(前回とは全然構造が変わってます)
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="FriendList">
<Require feature="opensocial-0.8"/>
</ModulePrefs>
<Content type="html"><![CDATA[
<STYLE type="text/css">
.fixinline {
display:-moz-inline-box;
-moz-box-align: center;
display: inline-block;
vertical-align: middle;
width:90px;
}
.thumimg {
margin: 5px;
vertical-align: middle;
}
</STYLE>
<div id="friendlist">
マイミク一覧を取得しています・・・
</div>
<script type="text/javascript">
var vfid = [];
var isOwner = false;
var owners;
var viewers;
gadgets.util.registerOnLoadHandler(function () {
//VIEWERのプロフィールとOWNERとVIEWERのマイミク一覧を取得
//opensocial.DataRequestオブジェクトを生成
var request = opensocial.newDataRequest();
//VIEWERのプロフィール取得リクエストを追加
request.add(request.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER),"viewer_data");
//newFetchPeopleRequestのオプションを指定
var fetchOpt = [];
fetchOpt[opensocial.DataRequest.PeopleRequestFields.MAX ] = 1000;
fetchOpt[opensocial.DataRequest.PeopleRequestFields.SORT_ORDER] = opensocial.DataRequest.SortOrder.NAME;
fetchOpt[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.PROFILE_URL];
//OWNERのマイミク取得リクエストを追加
var param = [];
param[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.OWNER;
param[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS";
var friends = opensocial.newIdSpec(param);
request.add(request.newFetchPeopleRequest(friends,fetchOpt),"owner_friends_data");
//VIEWERのマイミク取得リクエストを追加
var param = [];
param[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER;
param[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS";
var friends = opensocial.newIdSpec(param);
request.add(request.newFetchPeopleRequest(friends,fetchOpt),"viewer_friends_data");
//リクエストの送信
request.send(get_response_level1);
});
function get_response_level1(response) {
var item;
var i;
//取得したVIEWERのプロフィールでOWNERと同一人物かチェック
item = response.get("viewer_data");
if (item.hadError()) {
if (window.console) console.log("VIEWERプロフィールの取得に失敗:" + item.getErrorMessage());
return;
}
isOwner = item.getData().isOwner();
if (window.console) console.log("isOwner:" + isOwner);
//OWNERのマイミク一覧を取得
item = response.get("owner_friends_data");
if (item.hadError()) {
if (window.console) console.log("OWNERのマイミク取得に失敗:" + item.getErrorMessage());
return;
}
owners = item.getData().asArray();
if (window.console) console.log("対象:OWNER");
if (window.console) console.log("取得数:" + owners.length);
//VIEWERのマイミク一覧を取得
item = response.get("viewer_friends_data");
if (item.hadError()) {
if (window.console) console.log("VIEWERのマイミク取得に失敗:" + item.getErrorMessage());
return;
}
viewers = item.getData().asArray();
if (window.console) console.log("対象:VIEWER");
if (window.console) console.log("取得数:" + viewers.length);
//比較用にVIEWERのマイミクIDを配列にセット
for (i = 0; i < viewers.length; i++) {
vfid[viewers[i].getId()] = true;
};
//メッセージを消去
document.getElementById("friendlist").innerHTML = "";
//OWNERのマイミク一覧を表示
show_friends(owners,1,"friendlist");
//OWNERのマイミクのマイミクを取得し表示
setTimeout("get_friends_level2(0)",0);
}
function get_friends_level2(ocnt) {
//全てのOWNERのマイミクの処理を終えたら終了
if (owners.length <= ocnt) {
if (window.console) console.log("【処理終了!!】");
return;
}
//opensocial.DataRequestオブジェクトを生成
var request = opensocial.newDataRequest();
//newFetchPeopleRequestのオプションを指定
var fetchOpt = [];
fetchOpt[opensocial.DataRequest.PeopleRequestFields.MAX ] = 1000;
fetchOpt[opensocial.DataRequest.PeopleRequestFields.SORT_ORDER] = opensocial.DataRequest.SortOrder.NAME;
fetchOpt[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.PROFILE_URL];
//OWNERのマイミクのマイミク取得リクエストを追加
var ofid = owners[ocnt].getId();
var param = [];
param[opensocial.IdSpec.Field.USER_ID] = ofid;
param[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS";
var friends = opensocial.newIdSpec(param);
request.add(request.newFetchPeopleRequest(friends,fetchOpt),"friends_data");
if (window.console) console.log("--------------------");
if (window.console) console.log("Index:" + ocnt + ":(" + owners[ocnt].getDisplayName() + ")");
if (window.console) console.log(ofid);
//リクエストの送信
request.send(function (response) {
var item = response.get("friends_data");
if (item.hadError()) {
// エラー処理
if (window.console) console.log("OWNERのマイミクのマイミク取得に失敗:" + item.getErrorMessage());
return;
}
//マイミクの配列をセット
var people = item.getData().asArray();
if (window.console) console.log("対象:" + ofid);
if (window.console) console.log("取得数:" + people.length);
//OWNERのマイミクのマイミク一覧を表示
show_friends(people,2,"fid" + ofid);
//次のOWNERのマイミクのマイミクの処理を行う
setTimeout("get_friends_level2(" + (ocnt + 1) + ")",0);
});
}
//マイミク一覧の設定
function show_friends(people,level,elementId) {
//マイミク一覧の表示要素を設定
var element = document.getElementById(elementId);
//マイミク一覧の表示
var fcnt = 0;
var i;
for (i = 0; i < people.length; i++) {
//IDの取得
var gid = people[i].getId();
//ニックネームの取得
var nickname = people[i].getDisplayName();
//プロフィールURLの取得
var prourl = people[i].getField(opensocial.Person.Field.PROFILE_URL);
//サムネイルURLの取得
var thumurl = people[i].getField(opensocial.Person.Field.THUMBNAIL_URL);
if (level == 1) {
//閲覧者または共通の友人用メッセージの設定
var msg = "";
if (isOwner == false){
if (people[i].isViewer()){
msg = " (←あなた)";
} else if (gid in vfid){
msg = " (←共通の友人)";
}
}
//マイミク一覧の生成(マイミク用)
fcnt = fcnt + 1 ;
var ol = document.createElement('ol');
ol.id = "fid" + gid;
var div = document.createElement('div');
if (fcnt%2 == 0) {
div.style.backgroundColor = '#FFFFFF';
} else {
div.style.backgroundColor = '#FFF8E9';
}
div.innerHTML = "<span class='fixinline'><img src='" + thumurl + "' class='thumimg'></span><b><a href='" + prourl + "' target='_blank'>" + nickname + "</a></b>" + msg;
div.appendChild(ol);
element.appendChild(div);
} else {
//閲覧者または共通の友人用メッセージの設定
var msg = "";
if (people[i].isViewer()){
msg = " (←あなた)";
} else if (gid in vfid){
msg = " (←共通の友人)";
}
//マイミク一覧の生成(マイミクのマイミク用)
var li = document.createElement('li');
li.innerHTML = "<span class='fixinline'><img src='" + thumurl + "' class='thumimg'></span><a href='" + prourl + "' target='_blank'>" + nickname + "</a>" + msg;
element.appendChild(li);
}
};
}
</script>
]]></Content>
</Module>
やってみて思ったんですが、閲覧者=オーナーなのか判断するために、わざわざ閲覧者のプロフィール取得しなきゃいけないのは、ちと面倒ですな。( ̄з ̄)
インディーズアプリとして下記URLで公開していますので、興味のある方は試してみてください。
http://platform001.mixi.jp/view_appli.pl?id=1377
あと、UIを改良したいと思ってるんですが、それにはFlash化するしか無さそうな感じ。
Flash未経験なのでチャレンジするかは微妙だったりします。(^^;A
あぁ、日記に関するAPIを提供して欲しいなぁ・・・。
マイミクのマイミクさんが「友達の友達まで公開」に設定されている日記の更新状況を知りたくないですか?
そーすれば、マイミクにこだわる事無く緩く繋がれると思うので。
(案外みんな「友達まで公開」にしか設定してないかもしんないけど・・・。(^^;A)
【2009.06.18追記】
- 何となくメモリリークしている気がするので、get_friends_level2関数はsetTimeout関数経由で呼び出すよーに変更しました。
- mixiアプリの仕様変更でPROFILE_URLはPROFILE_DETAILSを指定しないと取得できなくなったので対応しました。