diff --git a/src/client/app.vue b/src/client/app.vue
index 6c84dd048..bdf860292 100644
--- a/src/client/app.vue
+++ b/src/client/app.vue
@@ -202,7 +202,7 @@ export default Vue.extend({
 		},
 
 		widgets(): any[] {
-			return this.$store.state.settings.widgets;
+			return this.$store.state.deviceUser.widgets;
 		}
 	},
 
@@ -233,7 +233,7 @@ export default Vue.extend({
 			this.connection.on('notification', this.onNotification);
 
 			if (this.widgets.length === 0) {
-				this.$store.dispatch('settings/setWidgets', [{
+				this.$store.commit('deviceUser/setWidgets', [{
 					name: 'calendar',
 					id: 'a', data: {}
 				}, {
@@ -504,8 +504,9 @@ export default Vue.extend({
 				this.$store.dispatch('switchAccount', {
 					...i,
 					token: token
+				}).then(() => {
+					location.reload();
 				});
-				location.reload();
 			});
 		},
 
@@ -552,7 +553,7 @@ export default Vue.extend({
 				items: widgets.map(widget => ({
 					text: this.$t('_widgets.' + widget),
 					action: () => {
-						this.$store.dispatch('settings/addWidget', {
+						this.$store.commit('deviceUser/addWidget', {
 							name: widget,
 							id: uuid(),
 							data: {}
@@ -564,11 +565,11 @@ export default Vue.extend({
 		},
 
 		removeWidget(widget) {
-			this.$store.dispatch('settings/removeWidget', widget);
+			this.$store.commit('deviceUser/removeWidget', widget);
 		},
 
 		saveHome() {
-			this.$store.dispatch('settings/setWidgets', this.widgets);
+			this.$store.commit('deviceUser/setWidgets', this.widgets);
 		}
 	}
 });
diff --git a/src/client/components/post-form.vue b/src/client/components/post-form.vue
index e089912e0..6716fa1b7 100644
--- a/src/client/components/post-form.vue
+++ b/src/client/components/post-form.vue
@@ -179,7 +179,7 @@ export default Vue.extend({
 
 	watch: {
 		localOnly() {
-			this.$store.commit('device/setLocalOnly', this.localOnly);
+			this.$store.commit('deviceUser/setLocalOnly', this.localOnly);
 		}
 	},
 
@@ -215,9 +215,9 @@ export default Vue.extend({
 		}
 
 		// デフォルト公開範囲
-		this.applyVisibility(this.$store.state.settings.rememberNoteVisibility ? this.$store.state.device.visibility : this.$store.state.settings.defaultNoteVisibility);
+		this.applyVisibility(this.$store.state.settings.rememberNoteVisibility ? this.$store.state.deviceUser.visibility : this.$store.state.settings.defaultNoteVisibility);
 
-		this.localOnly = this.$store.state.settings.rememberNoteVisibility ? this.$store.state.device.localOnly : this.$store.state.settings.defaultNoteLocalOnly;
+		this.localOnly = this.$store.state.settings.rememberNoteVisibility ? this.$store.state.deviceUser.localOnly : this.$store.state.settings.defaultNoteLocalOnly;
 
 		// 公開以外へのリプライ時は元の公開範囲を引き継ぐ
 		if (this.reply && ['home', 'followers', 'specified'].includes(this.reply.visibility)) {
diff --git a/src/client/components/visibility-chooser.vue b/src/client/components/visibility-chooser.vue
index 3bd2e17a1..28413fd83 100644
--- a/src/client/components/visibility-chooser.vue
+++ b/src/client/components/visibility-chooser.vue
@@ -56,14 +56,14 @@ export default Vue.extend({
 	},
 	data() {
 		return {
-			v: this.$store.state.settings.rememberNoteVisibility ? this.$store.state.device.visibility : (this.currentVisibility || this.$store.state.settings.defaultNoteVisibility),
+			v: this.$store.state.settings.rememberNoteVisibility ? this.$store.state.deviceUser.visibility : (this.currentVisibility || this.$store.state.settings.defaultNoteVisibility),
 			faGlobe, faUnlock, faEnvelope, faHome
 		}
 	},
 	methods: {
 		choose(visibility) {
 			if (this.$store.state.settings.rememberNoteVisibility) {
-				this.$store.commit('device/setVisibility', visibility);
+				this.$store.commit('deviceUser/setVisibility', visibility);
 			}
 			this.$emit('chosen', visibility);
 			this.destroyDom();
diff --git a/src/client/pages/index.home.vue b/src/client/pages/index.home.vue
index 48d25712e..0f32ca4a5 100644
--- a/src/client/pages/index.home.vue
+++ b/src/client/pages/index.home.vue
@@ -91,13 +91,12 @@ export default Vue.extend({
 				this.enableLocalTimeline = !meta.disableLocalTimeline || this.$store.state.i.isModerator || this.$store.state.i.isAdmin
 			) && ['local', 'social'].includes(this.src)) this.src = 'home';
 		});
-		if (this.$store.state.device.tl) {
-			this.src = this.$store.state.device.tl.src;
-			if (this.src === 'list') {
-				this.list = this.$store.state.device.tl.arg;
-			} else if (this.src === 'antenna') {
-				this.antenna = this.$store.state.device.tl.arg;
-			}
+
+		this.src = this.$store.state.deviceUser.tl.src;
+		if (this.src === 'list') {
+			this.list = this.$store.state.deviceUser.tl.arg;
+		} else if (this.src === 'antenna') {
+			this.antenna = this.$store.state.deviceUser.tl.arg;
 		}
 	},
 
@@ -164,7 +163,7 @@ export default Vue.extend({
 		},
 
 		saveSrc() {
-			this.$store.commit('device/setTl', {
+			this.$store.commit('deviceUser/setTl', {
 				src: this.src,
 				arg: this.src == 'list' ? this.list : this.antenna
 			});
diff --git a/src/client/store.ts b/src/client/store.ts
index 8e75e0acf..bd6187b91 100644
--- a/src/client/store.ts
+++ b/src/client/store.ts
@@ -16,7 +16,15 @@ const defaultSettings = {
 	wallpaper: null,
 	memo: null,
 	reactions: ['👍', '❤️', '😆', '🤔', '😮', '🎉', '💢', '😥', '😇', '🍮'],
-	widgets: []
+};
+
+const defaultDeviceUserSettings = {
+	visibility: 'public',
+	localOnly: false,
+	widgets: [],
+	tl: {
+		src: 'home'
+	},
 };
 
 const defaultDeviceSettings = {
@@ -27,16 +35,19 @@ const defaultDeviceSettings = {
 	autoReload: false,
 	accounts: [],
 	recentEmojis: [],
-	visibility: 'public',
-	localOnly: false,
 	themes: [],
 	theme: 'light',
 	animation: true,
+	userData: {},
 };
 
+function copy(data) {
+	return JSON.parse(JSON.stringify(data));
+}
+
 export default (os: MiOS) => new Vuex.Store({
 	plugins: [createPersistedState({
-		paths: ['i', 'device', 'settings']
+		paths: ['i', 'device', 'deviceUser', 'settings']
 	})],
 
 	state: {
@@ -58,10 +69,11 @@ export default (os: MiOS) => new Vuex.Store({
 	},
 
 	actions: {
-		login(ctx, i) {
+		async login(ctx, i) {
 			ctx.commit('updateI', i);
-			ctx.dispatch('settings/merge', i.clientData);
-			ctx.dispatch('addAcount', { id: i.id, i: localStorage.getItem('i') });
+			ctx.commit('settings/init', i.clientData);
+			ctx.commit('deviceUser/init', ctx.state.device.userData[i.id] || {});
+			await ctx.dispatch('addAcount', { id: i.id, i: localStorage.getItem('i') });
 		},
 
 		addAcount(ctx, info) {
@@ -74,14 +86,17 @@ export default (os: MiOS) => new Vuex.Store({
 		},
 
 		logout(ctx) {
+			ctx.commit('device/setUserData', { userId: ctx.state.i.id, data: ctx.state.deviceUser });
 			ctx.commit('updateI', null);
+			ctx.commit('settings/init', {});
+			ctx.commit('deviceUser/init', {});
 			localStorage.removeItem('i');
 		},
 
-		switchAccount(ctx, i) {
-			ctx.commit('updateI', i);
-			ctx.commit('settings/init', i.clientData);
+		async switchAccount(ctx, i) {
+			ctx.commit('device/setUserData', { userId: ctx.state.i.id, data: ctx.state.deviceUser });
 			localStorage.setItem('i', i.token);
+			await ctx.dispatch('login', i);
 		},
 
 		mergeMe(ctx, me) {
@@ -90,7 +105,7 @@ export default (os: MiOS) => new Vuex.Store({
 			}
 
 			if (me.clientData) {
-				ctx.dispatch('settings/merge', me.clientData);
+				ctx.commit('settings/init', me.clientData);
 			}
 		},
 	},
@@ -106,6 +121,32 @@ export default (os: MiOS) => new Vuex.Store({
 					state[x.key] = x.value;
 				},
 
+				setUserData(state, x: { userId: string; data: any }) {
+					state.userData[x.userId] = copy(x.data);
+				},
+			}
+		},
+
+		deviceUser: {
+			namespaced: true,
+
+			state: defaultDeviceUserSettings,
+
+			mutations: {
+				init(state, x) {
+					for (const [key, value] of Object.entries(defaultDeviceUserSettings)) {
+						if (x[key]) {
+							state[key] = x[key];
+						} else {
+							state[key] = value;
+						}
+					}
+				},
+
+				set(state, x: { key: string; value: any }) {
+					state[x.key] = x.value;
+				},
+
 				setTl(state, x) {
 					state.tl = {
 						src: x.src,
@@ -120,6 +161,25 @@ export default (os: MiOS) => new Vuex.Store({
 				setLocalOnly(state, localOnly) {
 					state.localOnly = localOnly;
 				},
+
+				setWidgets(state, widgets) {
+					state.widgets = widgets;
+				},
+
+				addWidget(state, widget) {
+					state.widgets.unshift(widget);
+				},
+
+				removeWidget(state, widget) {
+					state.widgets = state.widgets.filter(w => w.id != widget.id);
+				},
+
+				updateWidget(state, x) {
+					const w = state.widgets.find(w => w.id == x.id);
+					if (w) {
+						w.data = x.data;
+					}
+				},
 			}
 		},
 
@@ -145,13 +205,6 @@ export default (os: MiOS) => new Vuex.Store({
 			},
 
 			actions: {
-				merge(ctx, settings) {
-					if (settings == null) return;
-					for (const [key, value] of Object.entries(settings)) {
-						ctx.commit('set', { key, value });
-					}
-				},
-
 				set(ctx, x) {
 					ctx.commit('set', x);
 
@@ -162,41 +215,6 @@ export default (os: MiOS) => new Vuex.Store({
 						});
 					}
 				},
-
-				setWidgets(ctx, widgets) {
-					ctx.state.widgets = widgets;
-					ctx.dispatch('updateWidgets');
-				},
-
-				addWidget(ctx, widget) {
-					ctx.state.widgets.unshift(widget);
-					ctx.dispatch('updateWidgets');
-				},
-
-				removeWidget(ctx, widget) {
-					ctx.state.widgets = ctx.state.widgets.filter(w => w.id != widget.id);
-					ctx.dispatch('updateWidgets');
-				},
-
-				updateWidget(ctx, x) {
-					const w = ctx.state.widgets.find(w => w.id == x.id);
-					if (w) {
-						w.data = x.data;
-						ctx.dispatch('updateWidgets');
-					}
-				},
-
-				updateWidgets(ctx) {
-					const widgets = ctx.state.widgets;
-					ctx.commit('set', {
-						key: 'widgets',
-						value: widgets
-					});
-					os.api('i/update-client-setting', {
-						name: 'widgets',
-						value: widgets
-					});
-				},
 			}
 		}
 	}
diff --git a/src/client/widgets/define.ts b/src/client/widgets/define.ts
index 768446c12..96b1b4ab5 100644
--- a/src/client/widgets/define.ts
+++ b/src/client/widgets/define.ts
@@ -51,7 +51,7 @@ export default function <T extends object>(data: {
 			},
 
 			save() {
-				this.$store.dispatch('settings/updateWidget', this.widget);
+				this.$store.commit('deviceUser/updateWidget', this.widget);
 			}
 		}
 	});
diff --git a/src/services/note/read.ts b/src/services/note/read.ts
index 1cbe0e311..c87513f48 100644
--- a/src/services/note/read.ts
+++ b/src/services/note/read.ts
@@ -3,6 +3,8 @@ import { Note } from '../../models/entities/note';
 import { User } from '../../models/entities/user';
 import { NoteUnreads, Antennas, AntennaNotes, Users } from '../../models';
 
+// TODO: 状態が変化していない場合は各種イベントを送信しない
+
 /**
  * Mark a note as read
  */