///プロフィール情報 class ProfileInfo{ public string usercode;//VketID or uuid public string name;//ユーザ名 public string introduction;//登録してある自己紹介テキスト public string iconURL;//アイコンのURL(デフォルトならローカルにあるファイルを指す) public int followCount;//フォローしてる人数(お互いにログイン済みの場合のみ表示) public int followerCount;//フォロワー数(お互いにログイン済みの場合のみ表示) public string userType;//login or guest(ログインユーザなら"login",ゲストなら"guest") public bool isFollowUser;//自分がこのユーザをフォローしているかどうか } //ProfileModel g_ProfileModel; component ProfileModel { private bool isLoggedIn_; private ProfileInfo currentProfileInfo_; private const string base_layer_name="other_profile"; private const string default_icon_url="gui2024/menu/mypage/mypage_icon_none.png"; //コンストラクタ public ProfileModel() { //g_ProfileModel=this; isLoggedIn_=false; currentProfileInfo_ = new ProfileInfo(); } //現在選択チュノプレイヤーがログインユーザかどうかを返す //※ProfRejectorから利用されている関数 public bool IsLoggedIn(){ if(currentProfileInfo_.userType=="login"){ return true; } return false; } //他コンポーネント側から利用する場合はこの関数を呼び出してください //プレイヤーID(アバタークリックなどで取得できるプレイヤーID(ピアID))を取得し //最終的にそれに応じたプロフィールウィンドウを表示する //@param playerID プレイヤーID //@param isLoggedInSelf 自分自身がログインしているか public void FindUserDataAndShowProfile(string playerID,bool isLoggedInSelf ){ Player otherPlayer = hsPlayerGetByID(playerID); string userCode = GetUserCodeFromPlayer(otherPlayer); string userType = GetUserTypeFromPlayer(otherPlayer); FindUserDataAndShowProfileFromUserID(userCode,userType,isLoggedInSelf); } //ユーザIDからそれに応じたプロフィールウィンドウを表示する //@param userCode vket_idもしくはuuid //@param userType "login"か"guest" public void FindUserDataAndShowProfileFromUserID(string userCode,string userType,bool isLoggedInSelf){ isLoggedIn_=isLoggedInSelf; FetchUserProfile(userCode,userType); } //プレイヤーIDからユーザーコード(vket_id or uuid)を取得する //@param playerID アプリ中のプレイヤーID //@return Vketで使用されるユーザーID private string GetUserCodeFromPlayerID(string playerID){ Player otherPlayer = hsPlayerGetByID(playerID); return GetUserCodeFromPlayer(otherPlayer); } //プレイヤーからユーザーコードを取得 //ログインユーザの時はvket_id、非ログインユーザの時はuuid private string GetUserCodeFromPlayer(Player player){ if(player===null){ return ""; } return player.GetCustomState("UserCode"); } //プレイヤーからユーザータイプを取得 //ユーザタイプというのは"login" or "guest"のこと private string GetUserTypeFromPlayer(Player player){ if(player===null){ return ""; } return player.GetCustomState("UserType"); } //プロフィールに登録されているメッセージテキストを返す private string GetProfileMessage(){ return currentProfileInfo_.introduction; } //プロフィールのフォロー人数を返す private int GetFollowNum(){ return currentProfileInfo_.followCount; } //プロフィールのフォロワー人数を返す private int GetFollowerNum(){ return currentProfileInfo_.followerCount; } //アイコンのURLを返す(非ログインユーザの時はデフォルトアイコンのURIが入っている) private string GetIconURL(){ return currentProfileInfo_.iconURL; } //プロフィールのユーザーコード(ログインユーザの時はvket_id、非ログインユーザの時はuuidが入っている) public string GetUserCode(){ return currentProfileInfo_.usercode; } //設定されているユーザ名(ログインユーザの時はプロフィールのユーザ名、非ログインユーザの時はルーム入室時に設定したユーザ名) public string GetUserName(){ return currentProfileInfo_.name; } //現在ターゲッティングしているプレイヤーのプレイヤーIDを取得する public string GetCurrentPlayerID(){ string PlayerID; { LayerBundle layer = hsLayerGet("vcc_icon_only_base"); if(layer !== null) { Func GetPlayerIDFromUserCode = system.Layer_GetComponentMethod(layer.GetCurrent()._GetInstanceID(), "VCCViewModel", "GetPlayerIDFromUserCode"); if(!GetPlayerIDFromUserCode.IsEmpty()) PlayerID = GetPlayerIDFromUserCode(currentProfileInfo_.usercode); } } return PlayerID; } //表示上のフォロー数フォロワー数を更新して表示する private void RefreshDisplayFollowCount(){ //フォロー数の設定 string strFollowNum=""; string strFollowerNum=""; if(system.IsLangEN()){ strFollowNum = "%dFollowing" % GetFollowNum() ; strFollowerNum = "%dFollowers" % GetFollowerNum(); }else{ strFollowNum = "%dフォロー中" % GetFollowNum() ; strFollowerNum = "%dフォロワー" % GetFollowerNum(); } system.Canvas_SetGUIText(base_layer_name,"prof_follow_num", strFollowNum); system.Canvas_SetGUIText(base_layer_name,"prof_follower_num", strFollowerNum); } //最終的なプロフィールウィンドウを表示する private void ShowCurrentPlayerProfile(){ system.Canvas_SetGUIText(base_layer_name, "prof_id", GetUserCode()); system.Canvas_SetGUIText(base_layer_name,"prof_name", GetUserName()); //フォロー数の設定 RefreshDisplayFollowCount(); system.Canvas_SetGUIText(base_layer_name,"prof_text", GetProfileMessage()); system.Canvas_SetGUIImage(base_layer_name,"prof_avatar_icon",GetIconURL()); //ログインユーザがもっている情報を表示 RefreshDisplayUserData(); //プロフィールウィンドウを可視化する hsCanvasSetLayerShow(base_layer_name,true); } //現在選択中のプレイヤーがログイン済みかどうか private bool IsCurrentUserLoggedIn(){ if(currentProfileInfo_===null){ return false; } return currentProfileInfo_.userType=="login"; } //ログインユーザ用の情報を更新して表示、ログインユーザでないなら非表示 private void RefreshDisplayUserData(){ //現在ターゲッティングしてるユーザがログインユーザかどうか bool isLoggedInOther = IsCurrentUserLoggedIn(); const string logged_in_toggle="logged_in_toggle"; const string profile_followuser_toggle="profile_followuser_toggle"; const string other_logged_in_toggle="other_logged_in_toggle"; //いったんログインユーザ用のUIは消しておく hsCanvasResetToggleDefault(logged_in_toggle); hsCanvasResetToggleDefault(profile_followuser_toggle); hsCanvasResetToggleDefault(other_logged_in_toggle); //相手がログインしているなら、相手のユーザ情報を表示する if(isLoggedInOther){ hsCanvasToggleChange(other_logged_in_toggle); //自分も相手もログインしてるならフル表示 if(isLoggedIn_){ //このとき、相手をフォローしているかを取得しておく if(currentProfileInfo_.isFollowUser){ hsCanvasToggleChange(profile_followuser_toggle); } //自分==プロフィールならログインしてないのと同じことにする //(自分をフォローしたりできないようにする) Player thisPlayer=hsPlayerGet(); string thisVketID=GetUserCodeFromPlayer(thisPlayer); if(thisVketID==GetUserCode()){ return; }else{ hsCanvasToggleChange(logged_in_toggle); } } } } //ユーザーのプロフィールをHeliportから取得。対象ユーザーがログイン済みの場合と非ログインの場合で持ってくるものが違う //※自分のログイン情報で鳴く、相手のログイン情報なので注意 private void FetchUserProfile(string userCode,string userType){ currentProfileInfo_.userType=userType; if(userType=="login"){ // hsSystemOutputLog("await heliport.v3.api.profiles.fetchUserProfile('%s');\n" % userCode); heliport.v3.api.profiles.fetchUserProfile(_FetchUserProfileCallback,userCode); }else{ JsVal args = makeJsObj(); args.AddPropertyByVal("uuid", makeJsStrFrom(userCode)); args.AddPropertyByVal("onMissing", makeJsStrFrom("default")); heliport.v3.api.profiles.fetchUserGuestProfile(_FetchGuestUserProfileCallback, args); } } private void SetGuestUserInfo(string uuid,string name){ currentProfileInfo_.name = name; currentProfileInfo_.usercode = uuid; currentProfileInfo_.iconURL= default_icon_url;//デフォルトアイコン currentProfileInfo_.introduction=""; currentProfileInfo_.followCount=0; currentProfileInfo_.followerCount=0; } //ゲストプロフィール取得コールバック //相手からは「名前」しか取ってこれない //取ってきた後は表示まで行う private void _FetchGuestUserProfileCallback(JsVal val) { JsVal user = hsLoadReturnType(val).data; string uuid = user.GetProperty("uuid").GetStr(); string name = user.GetProperty("name").GetStr(); SetGuestUserInfo(uuid,name); ShowCurrentPlayerProfile(); } private string GetIconURLFromJsVal(JsVal user){ JsVal icon = user.GetProperty("icon");// if(icon !== null) { JsVal circle = icon.GetProperty("circle"); if(circle !== null){ JsVal url = circle.GetProperty("url"); if(url!==null){ //hsSystemOutputLog("circle.url = %s\n" % url.GetStr()); string urlStr = url.GetStr(); if(urlStr==""){ return default_icon_url; } return url.GetStr(); }else{ // hsSystemOutputLog("circle.url is null\n"); return default_icon_url;//デフォルトアイコン } }else{ // hsSystemOutputLog("circle is null\n"); return default_icon_url;//デフォルトアイコン } } // hsSystemOutputLog("icon is null\n"); return default_icon_url;//デフォルトアイコン } //ログイン済みプレイヤー情報取得コールバック //相手から、ユーザーID、名前、アイコンURL、自己紹介文、フォロー数、フォロワー数を取ってこれる //取ってきた後は表示まで行う void _FetchUserProfileCallback(JsVal val) { ReturnType result = hsLoadReturnType(val); if(!result.IsValid()) { // hsSystemOutputLog("result invalid\n"); return; } JsVal user = result.data; if(user === null){ // hsSystemOutputLog("user is null\n"); return; } string vketID = user.GetProperty("vket_id").GetStr(); string name = user.GetProperty("name").GetStr(); string iconURL=GetIconURLFromJsVal(user); // hsSystemOutputLog("iconurl is %s\n" % iconURL); string introduction = user.GetProperty("introduction").GetStr(); int follow = user.GetProperty("follow_count").GetNum(); int follower = user.GetProperty("follower_count").GetNum(); // 相手のユーザーデータを更新 currentProfileInfo_.usercode = vketID; currentProfileInfo_.name = name; currentProfileInfo_.iconURL= iconURL; currentProfileInfo_.introduction=introduction; currentProfileInfo_.followCount=follow; currentProfileInfo_.followerCount=follower; if(isLoggedIn_){ JsVal jsFollow = user.GetProperty("follow_status"); if(jsFollow !== null) currentProfileInfo_.isFollowUser = jsFollow.GetBool(); }else{ currentProfileInfo_.isFollowUser=false; } ShowCurrentPlayerProfile(); } //相手をフォローした時のコールバック関数 void _FetchUserFollowCallback(JsVal val) { ReturnType result = hsLoadReturnType(val); if(result.IsValid()){ currentProfileInfo_.followerCount++; RefreshDisplayFollowCount(); hsCanvasToggleChange("profile_followuser_toggle"); }else{ hsSystemOutput("フォローできません\n"); } } //相手へのフォローを解除した時のコールバック関数 void _FetchUserUnfollowCallback(JsVal val) { ReturnType result = hsLoadReturnType(val); if(result.IsValid()){ currentProfileInfo_.followerCount--; RefreshDisplayFollowCount(); hsCanvasToggleChange("profile_followuser_toggle"); } else{ hsSystemOutput("フォロー解除できません\n"); } } //キックバンブロックを行うためのレイヤーをひょじする private ProfRejector GetProfileRejector(){ //対象アバターを見えなくし、アバターターゲッティングも解除する LayerBundle optionLayer=hsLayerGet("prof_option_layer"); if(optionLayer===null){ return null; } ProfRejector rejector= system.Layer_GetComponentByName("prof_option_layer"); return rejector; } //プロフィールウィンドウ内のどのボタンを押したのか public void OnClickedButton(string layerName, string btnName){ if(layerName==base_layer_name){ if(btnName=="prof_open_myvket"){ // heliport.v3.api.profiles.openMyVketProfile(currentProfileInfo_.usercode); string CurrentUrl = GetCurrentUrl(); bool IsTest = (CurrentUrl.IndexOf("test") != -1 || CurrentUrl.IndexOf("localhost") != -1 || CurrentUrl.IndexOf("hikky.dev") != -1); string Domain = (IsTest)? "cloud.hikky.dev" : "cloud.vket.com"; string MyVketURL = "https://%s/profiles/%s" % Domain % currentProfileInfo_.usercode; hsWebOpen(MyVketURL); // ルームはカット //} else if(btnName=="prof_room"){ // heliport.v3.api.profiles.openMyVketMyRoom(currentProfileInfo_.usercode); }else if(btnName=="prof_message"){ heliport.v3.api.profiles.openMyVketMessage(); }else if(btnName=="prof_follow"){ heliport.v3.api.profiles.followUser(_FetchUserFollowCallback,currentProfileInfo_.usercode); }else if(btnName=="prof_unfollow"){ heliport.v3.api.profiles.unfollowUser(_FetchUserUnfollowCallback,currentProfileInfo_.usercode); } else if(btnName == "prof_close"){ // Community LayerBundle layer = hsLayerGet("mainmenu_community_base"); if(layer !== null) { layer.CallComponentMethod("CommunityMenuViewModel", "OnClickedCloseUserPlate", ""); } } //オプションボタンを押すとまた別レイヤーが立ち上がり遷移する if(btnName=="prof_btn_option"){ ProfRejector rejector=GetProfileRejector(); if(rejector===null){ hsSystemOutput("rejector is null\n"); return; } rejector.CheckAutority(); rejector.CheckBlocked(); const string block_loginuser_toggle="block_loginuser_toggle"; hsCanvasResetToggleDefault(block_loginuser_toggle); if(IsLoggedIn()){ hsCanvasToggleChange(block_loginuser_toggle); } hsCanvasSetLayerShow("prof_option_layer",true); } } } private string GetCurrentUrl() { JsVal val = heliport.v3.api.routers.getCurrentUrl(); ReturnType result = hsLoadReturnType(val); if(!result.IsValid()) return ""; return result.data.GetStr(); } }