Merge branch 'develop' into pizzax-indexeddb
							
								
								
									
										10
									
								
								CHANGELOG.md
									
										
									
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -7,6 +7,16 @@
 | 
			
		|||
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
## 12.x.x (unreleased)
 | 
			
		||||
 | 
			
		||||
### Changes
 | 
			
		||||
- Room機能が削除されました
 | 
			
		||||
  - 後日別リポジトリとして復活予定です
 | 
			
		||||
 | 
			
		||||
### Improvements
 | 
			
		||||
 | 
			
		||||
### Bugfixes
 | 
			
		||||
 | 
			
		||||
## 12.101.1 (2021/12/29)
 | 
			
		||||
 | 
			
		||||
### Bugfixes
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,17 +90,6 @@ Misskey uses Vue(v3) as its front-end framework.
 | 
			
		|||
**When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
 | 
			
		||||
Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
 | 
			
		||||
 | 
			
		||||
## Adding MisskeyRoom items
 | 
			
		||||
* Use English for material, object and texture names.
 | 
			
		||||
* Use meter for unit of length.
 | 
			
		||||
* Your PR should include all source files (e.g. `.png`, `.blend`) of your models (for later editing).
 | 
			
		||||
* Your PR must include the glTF binary files (`.glb`) of your models.
 | 
			
		||||
* Add a locale key `room.furnitures.YOUR_ITEM` at [`/locales/ja-JP.yml`](/locales/ja-JP.yml).
 | 
			
		||||
* Add a furniture definition at [`src/client/scripts/room/furnitures.json5`](src/client/scripts/room/furnitures.json5).
 | 
			
		||||
 | 
			
		||||
If you have no experience on 3D modeling, we suggest to use the free 3DCG software [Blender](https://www.blender.org/).
 | 
			
		||||
You can find information on glTF 2.0 at [glTF 2.0 — Blender Manual]( https://docs.blender.org/manual/en/dev/addons/io_scene_gltf2.html).
 | 
			
		||||
 | 
			
		||||
## Notes
 | 
			
		||||
### How to resolve conflictions occurred at yarn.lock?
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -537,7 +537,6 @@ yourAccountSuspendedDescription: "このアカウントは、サーバーの利
 | 
			
		|||
menu: "メニュー"
 | 
			
		||||
divider: "分割線"
 | 
			
		||||
addItem: "項目を追加"
 | 
			
		||||
rooms: "ルーム"
 | 
			
		||||
relays: "リレー"
 | 
			
		||||
addRelay: "リレーの追加"
 | 
			
		||||
inboxUrl: "inboxのURL"
 | 
			
		||||
| 
						 | 
				
			
			@ -1362,69 +1361,6 @@ _timelines:
 | 
			
		|||
  social: "ソーシャル"
 | 
			
		||||
  global: "グローバル"
 | 
			
		||||
 | 
			
		||||
_rooms:
 | 
			
		||||
  roomOf: "{user}のルーム"
 | 
			
		||||
  addFurniture: "家具を置く"
 | 
			
		||||
  translate: "移動"
 | 
			
		||||
  rotate: "回転"
 | 
			
		||||
  exit: "戻る"
 | 
			
		||||
  remove: "しまう"
 | 
			
		||||
  clear: "片付け"
 | 
			
		||||
  clearConfirm: "全ての家具をしまいますか?"
 | 
			
		||||
  leaveConfirm: "未保存の変更があります、移動しますか?"
 | 
			
		||||
  chooseImage: "画像を選択"
 | 
			
		||||
  roomType: "部屋のタイプ"
 | 
			
		||||
  carpetColor: "床の色"
 | 
			
		||||
  _roomType:
 | 
			
		||||
    default: "デフォルト"
 | 
			
		||||
    washitsu: "和室"
 | 
			
		||||
  _furnitures:
 | 
			
		||||
    milk: "牛乳パック"
 | 
			
		||||
    bed: "ベッド"
 | 
			
		||||
    low-table: "ローテーブル"
 | 
			
		||||
    desk: "デスク"
 | 
			
		||||
    chair: "チェア"
 | 
			
		||||
    chair2: "チェア2"
 | 
			
		||||
    fan: "換気扇"
 | 
			
		||||
    pc: "パソコン"
 | 
			
		||||
    plant: "観葉植物"
 | 
			
		||||
    plant2: "観葉植物2"
 | 
			
		||||
    eraser: "消しゴム"
 | 
			
		||||
    pencil: "鉛筆"
 | 
			
		||||
    pudding: "プリン"
 | 
			
		||||
    cardboard-box: "段ボール箱"
 | 
			
		||||
    cardboard-box2: "段ボール箱2"
 | 
			
		||||
    cardboard-box3: "段ボール箱3"
 | 
			
		||||
    book: "本"
 | 
			
		||||
    book2: "本2"
 | 
			
		||||
    piano: "ピアノ"
 | 
			
		||||
    facial-tissue: "ティッシュボックス"
 | 
			
		||||
    server: "サーバー"
 | 
			
		||||
    moon: "月"
 | 
			
		||||
    corkboard: "コルクボード"
 | 
			
		||||
    mousepad: "マウスパッド"
 | 
			
		||||
    monitor: "モニター"
 | 
			
		||||
    keyboard: "キーボード"
 | 
			
		||||
    carpet-stripe: "カーペット(縞)"
 | 
			
		||||
    mat: "マット"
 | 
			
		||||
    color-box: "カラーボックス"
 | 
			
		||||
    wall-clock: "壁掛け時計"
 | 
			
		||||
    photoframe: "額縁"
 | 
			
		||||
    cube: "キューブ"
 | 
			
		||||
    tv: "テレビ"
 | 
			
		||||
    pinguin: "ピンギン"
 | 
			
		||||
    rubik-cube: "ルービックキューブ"
 | 
			
		||||
    poster-h: "ポスター(横長)"
 | 
			
		||||
    poster-v: "ポスター(縦長)"
 | 
			
		||||
    sofa: "ソファ"
 | 
			
		||||
    spiral: "螺旋階段"
 | 
			
		||||
    bin: "ゴミ箱"
 | 
			
		||||
    cup-noodle: "カップ麺"
 | 
			
		||||
    holo-display: "ホログラフィックディスプレイ"
 | 
			
		||||
    energy-drink: "エナジードリンク"
 | 
			
		||||
    doll-ai: "藍ちゃん人形"
 | 
			
		||||
    banknote: "札束"
 | 
			
		||||
 | 
			
		||||
_pages:
 | 
			
		||||
  newPage: "ページの作成"
 | 
			
		||||
  editPage: "ページの編集"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,6 +124,7 @@ export class UserProfile {
 | 
			
		|||
	})
 | 
			
		||||
	public clientData: Record<string, any>;
 | 
			
		||||
 | 
			
		||||
	// TODO: そのうち消す
 | 
			
		||||
	@Column('jsonb', {
 | 
			
		||||
		default: {},
 | 
			
		||||
		comment: 'The room data of the User.',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,160 +0,0 @@
 | 
			
		|||
import $ from 'cafy';
 | 
			
		||||
import define from '../../define';
 | 
			
		||||
import { ApiError } from '../../error';
 | 
			
		||||
import { Users, UserProfiles } from '@/models/index';
 | 
			
		||||
import { ID } from '@/misc/cafy-id';
 | 
			
		||||
import { toPunyNullable } from '@/misc/convert-host';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['room'],
 | 
			
		||||
 | 
			
		||||
	requireCredential: false as const,
 | 
			
		||||
 | 
			
		||||
	params: {
 | 
			
		||||
		userId: {
 | 
			
		||||
			validator: $.optional.type(ID),
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		username: {
 | 
			
		||||
			validator: $.optional.str,
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		host: {
 | 
			
		||||
			validator: $.optional.nullable.str,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	errors: {
 | 
			
		||||
		noSuchUser: {
 | 
			
		||||
			message: 'No such user.',
 | 
			
		||||
			code: 'NO_SUCH_USER',
 | 
			
		||||
			id: '7ad3fa3e-5e12-42f0-b23a-f3d13f10ee4b',
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	res: {
 | 
			
		||||
		type: 'object' as const,
 | 
			
		||||
		optional: false as const, nullable: false as const,
 | 
			
		||||
		properties: {
 | 
			
		||||
			roomType: {
 | 
			
		||||
				type: 'string' as const,
 | 
			
		||||
				optional: false as const, nullable: false as const,
 | 
			
		||||
				enum: ['default', 'washitsu'],
 | 
			
		||||
			},
 | 
			
		||||
			furnitures: {
 | 
			
		||||
				type: 'array' as const,
 | 
			
		||||
				optional: false as const, nullable: false as const,
 | 
			
		||||
				items: {
 | 
			
		||||
					type: 'object' as const,
 | 
			
		||||
					optional: false as const, nullable: false as const,
 | 
			
		||||
					properties: {
 | 
			
		||||
						id: {
 | 
			
		||||
							type: 'string' as const,
 | 
			
		||||
							optional: false as const, nullable: false as const,
 | 
			
		||||
						},
 | 
			
		||||
						type: {
 | 
			
		||||
							type: 'string' as const,
 | 
			
		||||
							optional: false as const, nullable: false as const,
 | 
			
		||||
						},
 | 
			
		||||
						props: {
 | 
			
		||||
							type: 'object' as const,
 | 
			
		||||
							optional: true as const, nullable: false as const,
 | 
			
		||||
						},
 | 
			
		||||
						position: {
 | 
			
		||||
							type: 'object' as const,
 | 
			
		||||
							optional: false as const, nullable: false as const,
 | 
			
		||||
							properties: {
 | 
			
		||||
								x: {
 | 
			
		||||
									type: 'number' as const,
 | 
			
		||||
									optional: false as const, nullable: false as const,
 | 
			
		||||
								},
 | 
			
		||||
								y: {
 | 
			
		||||
									type: 'number' as const,
 | 
			
		||||
									optional: false as const, nullable: false as const,
 | 
			
		||||
								},
 | 
			
		||||
								z: {
 | 
			
		||||
									type: 'number' as const,
 | 
			
		||||
									optional: false as const, nullable: false as const,
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
						rotation: {
 | 
			
		||||
							type: 'object' as const,
 | 
			
		||||
							optional: false as const, nullable: false as const,
 | 
			
		||||
							properties: {
 | 
			
		||||
								x: {
 | 
			
		||||
									type: 'number' as const,
 | 
			
		||||
									optional: false as const, nullable: false as const,
 | 
			
		||||
								},
 | 
			
		||||
								y: {
 | 
			
		||||
									type: 'number' as const,
 | 
			
		||||
									optional: false as const, nullable: false as const,
 | 
			
		||||
								},
 | 
			
		||||
								z: {
 | 
			
		||||
									type: 'number' as const,
 | 
			
		||||
									optional: false as const, nullable: false as const,
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			carpetColor: {
 | 
			
		||||
				type: 'string' as const,
 | 
			
		||||
				optional: false as const, nullable: false as const,
 | 
			
		||||
				format: 'hex',
 | 
			
		||||
				example: '#85CAF0',
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
export default define(meta, async (ps, me) => {
 | 
			
		||||
	const user = await Users.findOne(ps.userId != null
 | 
			
		||||
		? { id: ps.userId }
 | 
			
		||||
		: { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) });
 | 
			
		||||
 | 
			
		||||
	if (user == null) {
 | 
			
		||||
		throw new ApiError(meta.errors.noSuchUser);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const profile = await UserProfiles.findOneOrFail(user.id);
 | 
			
		||||
 | 
			
		||||
	if (profile.room.furnitures == null) {
 | 
			
		||||
		await UserProfiles.update(user.id, {
 | 
			
		||||
			room: {
 | 
			
		||||
				furnitures: [],
 | 
			
		||||
				...profile.room,
 | 
			
		||||
			},
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		profile.room.furnitures = [];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (profile.room.roomType == null) {
 | 
			
		||||
		const initialType = 'default';
 | 
			
		||||
		await UserProfiles.update(user.id, {
 | 
			
		||||
			room: {
 | 
			
		||||
				roomType: initialType as any,
 | 
			
		||||
				...profile.room,
 | 
			
		||||
			},
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		profile.room.roomType = initialType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (profile.room.carpetColor == null) {
 | 
			
		||||
		const initialColor = '#85CAF0';
 | 
			
		||||
		await UserProfiles.update(user.id, {
 | 
			
		||||
			room: {
 | 
			
		||||
				carpetColor: initialColor as any,
 | 
			
		||||
				...profile.room,
 | 
			
		||||
			},
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		profile.room.carpetColor = initialColor;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return profile.room;
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -1,52 +0,0 @@
 | 
			
		|||
import $ from 'cafy';
 | 
			
		||||
import { publishMainStream } from '@/services/stream';
 | 
			
		||||
import define from '../../define';
 | 
			
		||||
import { Users, UserProfiles } from '@/models/index';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['room'],
 | 
			
		||||
 | 
			
		||||
	requireCredential: true as const,
 | 
			
		||||
 | 
			
		||||
	params: {
 | 
			
		||||
		room: {
 | 
			
		||||
			validator: $.obj({
 | 
			
		||||
				furnitures: $.arr($.obj({
 | 
			
		||||
					id: $.str,
 | 
			
		||||
					type: $.str,
 | 
			
		||||
					position: $.obj({
 | 
			
		||||
						x: $.num,
 | 
			
		||||
						y: $.num,
 | 
			
		||||
						z: $.num,
 | 
			
		||||
					}),
 | 
			
		||||
					rotation: $.obj({
 | 
			
		||||
						x: $.num,
 | 
			
		||||
						y: $.num,
 | 
			
		||||
						z: $.num,
 | 
			
		||||
					}),
 | 
			
		||||
					props: $.optional.nullable.obj(),
 | 
			
		||||
				})),
 | 
			
		||||
				roomType: $.str,
 | 
			
		||||
				carpetColor: $.str,
 | 
			
		||||
			}),
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
export default define(meta, async (ps, user) => {
 | 
			
		||||
	await UserProfiles.update(user.id, {
 | 
			
		||||
		room: ps.room as any,
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const iObj = await Users.pack(user.id, user, {
 | 
			
		||||
		detail: true,
 | 
			
		||||
		includeSecrets: true,
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// Publish meUpdated event
 | 
			
		||||
	publishMainStream(user.id, 'meUpdated', iObj);
 | 
			
		||||
 | 
			
		||||
	// TODO: レスポンスがおかしいと思う by YuzuRyo61
 | 
			
		||||
	return iObj;
 | 
			
		||||
});
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 43 KiB  | 
| 
		 Before Width: | Height: | Size: 3.4 KiB  | 
| 
		 Before Width: | Height: | Size: 60 KiB  | 
| 
		 Before Width: | Height: | Size: 8.4 KiB  | 
| 
		 Before Width: | Height: | Size: 16 KiB  | 
| 
		 Before Width: | Height: | Size: 4.5 KiB  | 
| 
		 Before Width: | Height: | Size: 16 KiB  | 
| 
		 Before Width: | Height: | Size: 3.5 KiB  | 
| 
		 Before Width: | Height: | Size: 290 KiB  | 
| 
		 Before Width: | Height: | Size: 10 KiB  | 
| 
		 Before Width: | Height: | Size: 124 KiB  | 
| 
		 Before Width: | Height: | Size: 22 KiB  | 
| 
		 Before Width: | Height: | Size: 8.1 KiB  | 
| 
		 Before Width: | Height: | Size: 11 KiB  | 
| 
		 Before Width: | Height: | Size: 4.4 KiB  | 
| 
		 Before Width: | Height: | Size: 688 B  | 
| 
		 Before Width: | Height: | Size: 20 KiB  | 
| 
		 Before Width: | Height: | Size: 102 KiB  | 
| 
		 Before Width: | Height: | Size: 16 KiB  | 
| 
		 Before Width: | Height: | Size: 658 B  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 24 KiB  | 
| 
		 Before Width: | Height: | Size: 85 KiB  | 
| 
		 Before Width: | Height: | Size: 2.9 KiB  | 
| 
		 Before Width: | Height: | Size: 63 KiB  |