This commit is contained in:
		| @@ -13,6 +13,15 @@ common: | |||||||
|     months_ago: "{}month(s) ago" |     months_ago: "{}month(s) ago" | ||||||
|     years_ago: "{}year(s) ago" |     years_ago: "{}year(s) ago" | ||||||
|  |  | ||||||
|  |   weekday-short: | ||||||
|  |     sunday: "S" | ||||||
|  |     monday: "M" | ||||||
|  |     tuesday: "T" | ||||||
|  |     wednesday: "W" | ||||||
|  |     thursday: "T" | ||||||
|  |     friday: "F" | ||||||
|  |     satruday: "S" | ||||||
|  |  | ||||||
|   reactions: |   reactions: | ||||||
|     like: "Like" |     like: "Like" | ||||||
|     love: "Love" |     love: "Love" | ||||||
|   | |||||||
| @@ -13,6 +13,15 @@ common: | |||||||
|     months_ago: "{}ヶ月前" |     months_ago: "{}ヶ月前" | ||||||
|     years_ago: "{}年前" |     years_ago: "{}年前" | ||||||
|  |  | ||||||
|  |   weekday-short: | ||||||
|  |     sunday: "日" | ||||||
|  |     monday: "月" | ||||||
|  |     tuesday: "火" | ||||||
|  |     wednesday: "水" | ||||||
|  |     thursday: "木" | ||||||
|  |     friday: "金" | ||||||
|  |     satruday: "土" | ||||||
|  |  | ||||||
|   reactions: |   reactions: | ||||||
|     like: "いいね" |     like: "いいね" | ||||||
|     love: "ハート" |     love: "ハート" | ||||||
|   | |||||||
| @@ -29,9 +29,17 @@ module.exports = async (params, user, app) => { | |||||||
| 	const [maxId, maxIdErr] = $(params.max_id).optional.id().$; | 	const [maxId, maxIdErr] = $(params.max_id).optional.id().$; | ||||||
| 	if (maxIdErr) throw 'invalid max_id param'; | 	if (maxIdErr) throw 'invalid max_id param'; | ||||||
|  |  | ||||||
| 	// Check if both of since_id and max_id is specified | 	// Get 'since_date' parameter | ||||||
| 	if (sinceId && maxId) { | 	const [sinceDate, sinceDateErr] = $(params.since_date).optional.number().$; | ||||||
| 		throw 'cannot set since_id and max_id'; | 	if (sinceDateErr) throw 'invalid since_date param'; | ||||||
|  |  | ||||||
|  | 	// Get 'max_date' parameter | ||||||
|  | 	const [maxDate, maxDateErr] = $(params.max_date).optional.number().$; | ||||||
|  | 	if (maxDateErr) throw 'invalid max_date param'; | ||||||
|  |  | ||||||
|  | 	// Check if only one of since_id, max_id, since_date, max_date specified | ||||||
|  | 	if ([sinceId, maxId, sinceDate, maxDate].filter(x => x != null).length > 1) { | ||||||
|  | 		throw 'only one of since_id, max_id, since_date, max_date can be specified'; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	const { followingIds, watchingChannelIds } = await rap({ | 	const { followingIds, watchingChannelIds } = await rap({ | ||||||
| @@ -81,6 +89,15 @@ module.exports = async (params, user, app) => { | |||||||
| 		query._id = { | 		query._id = { | ||||||
| 			$lt: maxId | 			$lt: maxId | ||||||
| 		}; | 		}; | ||||||
|  | 	} else if (sinceDate) { | ||||||
|  | 		sort._id = 1; | ||||||
|  | 		query.created_at = { | ||||||
|  | 			$gt: new Date(sinceDate) | ||||||
|  | 		}; | ||||||
|  | 	} else if (maxDate) { | ||||||
|  | 		query.created_at = { | ||||||
|  | 			$lt: new Date(maxDate) | ||||||
|  | 		}; | ||||||
| 	} | 	} | ||||||
| 	//#endregion | 	//#endregion | ||||||
|  |  | ||||||
|   | |||||||
| @@ -70,7 +70,13 @@ | |||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		this.load = (cb) => { | 		this.load = (cb) => { | ||||||
| 			this.api('posts/timeline').then(posts => { | 			this.update({ | ||||||
|  | 				isLoading: true | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			this.api('posts/timeline', { | ||||||
|  | 				max_date: this.date ? this.date.getTime() : undefined | ||||||
|  | 			}).then(posts => { | ||||||
| 				this.update({ | 				this.update({ | ||||||
| 					isLoading: false, | 					isLoading: false, | ||||||
| 					isEmpty: posts.length == 0 | 					isEmpty: posts.length == 0 | ||||||
| @@ -114,5 +120,15 @@ | |||||||
| 			const current = window.scrollY + window.innerHeight; | 			const current = window.scrollY + window.innerHeight; | ||||||
| 			if (current > document.body.offsetHeight - 8) this.more(); | 			if (current > document.body.offsetHeight - 8) this.more(); | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
|  | 		this.warp = date => { | ||||||
|  | 			console.log(date); | ||||||
|  |  | ||||||
|  | 			this.update({ | ||||||
|  | 				date: date | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			this.load(); | ||||||
|  | 		}; | ||||||
| 	</script> | 	</script> | ||||||
| </mk-timeline-home-widget> | </mk-timeline-home-widget> | ||||||
|   | |||||||
							
								
								
									
										165
									
								
								src/web/app/desktop/tags/home-widgets/timemachine.tag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								src/web/app/desktop/tags/home-widgets/timemachine.tag
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | |||||||
|  | <mk-timemachine-home-widget> | ||||||
|  | 	<button onclick={ prev }><i class="fa fa-chevron-circle-left"></i></button> | ||||||
|  | 	<p class="title">{ year }/{ month }</p> | ||||||
|  | 	<button onclick={ next }><i class="fa fa-chevron-circle-right"></i></button> | ||||||
|  |  | ||||||
|  | 	<div class="calendar"> | ||||||
|  | 		<div class="weekday" each={ day, i in Array(7).fill(0) }>{ weekdayText[i] }</div> | ||||||
|  | 		<div each={ day, i in Array(paddingDays).fill(0) }></div> | ||||||
|  | 		<div class="day" each={ day, i in Array(days).fill(0) } data-today={ isToday(i + 1) } onclick={ go.bind(null, i + 1) }>{ i + 1 }</div> | ||||||
|  | 	</div> | ||||||
|  | 	<style> | ||||||
|  | 		:scope | ||||||
|  | 			display block | ||||||
|  | 			color #777 | ||||||
|  | 			background #fff | ||||||
|  |  | ||||||
|  | 			> .title | ||||||
|  | 				z-index 1 | ||||||
|  | 				margin 0 | ||||||
|  | 				padding 0 16px | ||||||
|  | 				text-align center | ||||||
|  | 				line-height 42px | ||||||
|  | 				font-size 0.9em | ||||||
|  | 				font-weight bold | ||||||
|  | 				color #888 | ||||||
|  | 				box-shadow 0 1px rgba(0, 0, 0, 0.07) | ||||||
|  |  | ||||||
|  | 				> i | ||||||
|  | 					margin-right 4px | ||||||
|  |  | ||||||
|  | 			> button | ||||||
|  | 				position absolute | ||||||
|  | 				z-index 2 | ||||||
|  | 				top 0 | ||||||
|  | 				padding 0 | ||||||
|  | 				width 42px | ||||||
|  | 				font-size 0.9em | ||||||
|  | 				line-height 42px | ||||||
|  | 				color #ccc | ||||||
|  |  | ||||||
|  | 				&:hover | ||||||
|  | 					color #aaa | ||||||
|  |  | ||||||
|  | 				&:active | ||||||
|  | 					color #999 | ||||||
|  |  | ||||||
|  | 				&:first-of-type | ||||||
|  | 					left 0 | ||||||
|  |  | ||||||
|  | 				&:last-of-type | ||||||
|  | 					right 0 | ||||||
|  |  | ||||||
|  | 			> .calendar | ||||||
|  | 				display flex | ||||||
|  | 				flex-wrap wrap | ||||||
|  | 				padding 16px | ||||||
|  |  | ||||||
|  | 				> div | ||||||
|  | 					width calc(100% * (1/7)) | ||||||
|  | 					text-align center | ||||||
|  | 					line-height 32px | ||||||
|  | 					font-size 14px | ||||||
|  |  | ||||||
|  | 					&.weekday | ||||||
|  | 						color #19a2a9 | ||||||
|  |  | ||||||
|  | 					&.day | ||||||
|  | 						cursor pointer | ||||||
|  |  | ||||||
|  | 						&:hover | ||||||
|  | 							background rgba(0, 0, 0, 0.025) | ||||||
|  |  | ||||||
|  | 						&:active | ||||||
|  | 							background rgba(0, 0, 0, 0.05) | ||||||
|  |  | ||||||
|  | 						&[data-today] | ||||||
|  | 							color $theme-color-foreground | ||||||
|  | 							background $theme-color | ||||||
|  |  | ||||||
|  | 							&:hover | ||||||
|  | 								background lighten($theme-color, 10%) | ||||||
|  |  | ||||||
|  | 							&:active | ||||||
|  | 								background darken($theme-color, 10%) | ||||||
|  |  | ||||||
|  | 	</style> | ||||||
|  | 	<script> | ||||||
|  | 		const eachMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; | ||||||
|  |  | ||||||
|  | 		function isLeapYear(year) { | ||||||
|  | 			return (year % 400 == 0) ? true : | ||||||
|  | 				(year % 100 == 0) ? false : | ||||||
|  | 					(year % 4 == 0) ? true : | ||||||
|  | 						false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		this.today = new Date(); | ||||||
|  | 		this.year = this.today.getFullYear(); | ||||||
|  | 		this.month = this.today.getMonth() + 1; | ||||||
|  | 		this.weekdayText = [ | ||||||
|  | 			'%i18n:common.weekday-short.sunday%', | ||||||
|  | 			'%i18n:common.weekday-short.monday%', | ||||||
|  | 			'%i18n:common.weekday-short.tuesday%', | ||||||
|  | 			'%i18n:common.weekday-short.wednesday%', | ||||||
|  | 			'%i18n:common.weekday-short.thursday%', | ||||||
|  | 			'%i18n:common.weekday-short.friday%', | ||||||
|  | 			'%i18n:common.weekday-short.satruday%' | ||||||
|  | 		]; | ||||||
|  |  | ||||||
|  | 		this.on('mount', () => { | ||||||
|  | 			this.calc(); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		this.isToday = day => { | ||||||
|  | 			return this.year == this.today.getFullYear() && this.month == this.today.getMonth() + 1 && day == this.today.getDate(); | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		this.calc = () => { | ||||||
|  | 			let days = eachMonthDays[this.month - 1]; | ||||||
|  |  | ||||||
|  | 			// うるう年なら+1日 | ||||||
|  | 			if (this.month == 2 && isLeapYear(this.year)) days++; | ||||||
|  |  | ||||||
|  | 			const date = new Date(this.year, this.month - 1, 1); | ||||||
|  | 			const weekday = date.getDay(); | ||||||
|  |  | ||||||
|  | 			this.update({ | ||||||
|  | 				paddingDays: weekday, | ||||||
|  | 				days: days | ||||||
|  | 			}); | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		this.prev = () => { | ||||||
|  | 			if (this.month == 1) { | ||||||
|  | 				this.update({ | ||||||
|  | 					year: this.year - 1, | ||||||
|  | 					month: 12 | ||||||
|  | 				}); | ||||||
|  | 			} else { | ||||||
|  | 				this.update({ | ||||||
|  | 					month: this.month - 1 | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 			this.calc(); | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		this.next = () => { | ||||||
|  | 			if (this.month == 12) { | ||||||
|  | 				this.update({ | ||||||
|  | 					year: this.year + 1, | ||||||
|  | 					month: 1 | ||||||
|  | 				}); | ||||||
|  | 			} else { | ||||||
|  | 				this.update({ | ||||||
|  | 					month: this.month + 1 | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 			this.calc(); | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		this.go = day => { | ||||||
|  | 			this.opts.tl.warp(new Date(this.year, this.month - 1, day, 23, 59, 59, 999)); | ||||||
|  | 		}; | ||||||
|  | </script> | ||||||
|  | </mk-timemachine-home-widget> | ||||||
| @@ -5,6 +5,7 @@ | |||||||
| 			<select ref="widgetSelector"> | 			<select ref="widgetSelector"> | ||||||
| 				<option value="profile">プロフィール</option> | 				<option value="profile">プロフィール</option> | ||||||
| 				<option value="calendar">カレンダー</option> | 				<option value="calendar">カレンダー</option> | ||||||
|  | 				<option value="timemachine">カレンダー(タイムマシン)</option> | ||||||
| 				<option value="activity">アクティビティ</option> | 				<option value="activity">アクティビティ</option> | ||||||
| 				<option value="rss-reader">RSSリーダー</option> | 				<option value="rss-reader">RSSリーダー</option> | ||||||
| 				<option value="trends">トレンド</option> | 				<option value="trends">トレンド</option> | ||||||
| @@ -214,7 +215,8 @@ | |||||||
|  |  | ||||||
| 			this.home.push(riot.mount(el, { | 			this.home.push(riot.mount(el, { | ||||||
| 				id: widget.id, | 				id: widget.id, | ||||||
| 				data: widget.data | 				data: widget.data, | ||||||
|  | 				tl: this.refs.tl | ||||||
| 			})[0]); | 			})[0]); | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,6 +41,7 @@ require('./home-widgets/activity.tag'); | |||||||
| require('./home-widgets/server.tag'); | require('./home-widgets/server.tag'); | ||||||
| require('./home-widgets/slideshow.tag'); | require('./home-widgets/slideshow.tag'); | ||||||
| require('./home-widgets/channel.tag'); | require('./home-widgets/channel.tag'); | ||||||
|  | require('./home-widgets/timemachine.tag'); | ||||||
| require('./timeline.tag'); | require('./timeline.tag'); | ||||||
| require('./messaging/window.tag'); | require('./messaging/window.tag'); | ||||||
| require('./messaging/room-window.tag'); | require('./messaging/room-window.tag'); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo