Skip to content

Commit 5610f60

Browse files
authored
Merge pull request #630 from JQinglong/feature/movieSelector
動画検索対象切り替え対応
2 parents 0a21d89 + fc38f3e commit 5610f60

File tree

8 files changed

+282681
-48
lines changed

8 files changed

+282681
-48
lines changed

src/assets/locales/ja.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
"date": "日付設定",
8080
"time": "時間設定",
8181
"subject_label_color": "ラベル色",
82-
"video_keyword": "オプション機能:{source}の動画検索",
82+
"video_keyword": "オプション機能:動画検索",
8383
"video_url": "参考動画URL",
8484
"video_thumbnail": "動画サムネイル・キャプション表示",
8585
"textbook_page": "教科書ページ",
@@ -92,7 +92,7 @@
9292
"required": "*マークのあるものは必須項目です",
9393
"search_videos": {
9494
"search": "検索",
95-
"search_result": "{source}の動画検索結果",
95+
"search_result": "動画検索結果",
9696
"add_to_video_urls": "参考動画URLに登録する"
9797
}
9898
},

src/components/EditLessonScreenInner3.vue

Lines changed: 91 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,18 @@
99
<div class="VideoSearch">
1010
<editor-input-field-pickable
1111
v-model="videoSearchWord"
12-
:title="
13-
$t('components.editing_screen.labels.video_keyword', {
14-
source: 'NHK For School',
15-
})
16-
"
12+
selector="video"
13+
:title="$t('components.editing_screen.labels.video_keyword')"
1714
:placeholder="$t('components.editing_screen.placeholder.video_keyword')"
1815
icon-name="mdi-magnify"
1916
:button-text="$t('components.editing_screen.search_videos.search')"
2017
@clickButton="handleVideoSearchWord"
18+
@changeMovie="handleChangeMovie"
2119
/>
2220

2321
<div v-if="videoSearchResult.length > 0" class="SearchResult">
2422
<h3 class="SearchResultTitle">
25-
{{
26-
$t('components.editing_screen.search_videos.search_result', {
27-
source: 'NHK For School',
28-
})
29-
}}
23+
{{ $t('components.editing_screen.search_videos.search_result') }}
3024
</h3>
3125
<ul class="SearchResultList">
3226
<li v-for="(v, i) in displayLists" :key="i" class="SearchResultItem">
@@ -54,7 +48,13 @@
5448
v-if="v.videoUrl"
5549
class="SearchResultButton"
5650
color="#338dce"
57-
@click="registerVideoUrl(v.videoUrl)"
51+
@click="
52+
registerVideoUrl(
53+
v.videoUrl,
54+
v.videoTitle,
55+
v.videoThumbnailUrl
56+
)
57+
"
5858
>
5959
<v-icon color="white"> mdi-link </v-icon>
6060
{{
@@ -81,12 +81,16 @@
8181
<script lang="ts">
8282
import { Vue, Component, Prop, Emit, Watch } from 'vue-property-decorator'
8383
import EditorInputFieldPickable from '~/components/EditorInputFieldPickable.vue'
84+
import { MovieListItem, Movie } from '~/types/movies'
8485
85-
let movies: any[] = []
86+
let movies: Movie[] = []
8687
8788
export type formData = {
8889
videoUrl: string | null
8990
videoTitle: string
91+
videoSubTitle: string | null
92+
videoDescription: string | null
93+
videoPlayTime: string | null
9094
videoThumbnailUrl: string | null
9195
}
9296
@@ -99,6 +103,9 @@ export default class EditLessonScreenInner3 extends Vue {
99103
tempFormData = {
100104
videoUrl: this.form.videoUrl,
101105
videoTitle: this.form.videoTitle,
106+
videoSubTitle: this.form.videoSubTitle,
107+
videoDescription: this.form.videoDescription,
108+
videoPlayTime: this.form.videoPlayTime,
102109
videoThumbnailUrl:
103110
this.form.videoThumbnailUrl !== '' ? this.form.videoThumbnailUrl : null,
104111
}
@@ -109,24 +116,28 @@ export default class EditLessonScreenInner3 extends Vue {
109116
default: () => ({
110117
videoUrl: null,
111118
videoTitle: '',
119+
videoSubTitle: '',
120+
videoDescription: '',
121+
videoPlayTime: '',
112122
videoThumbnailUrl: '',
113123
}),
114124
})
115125
public value!: formData
116126
127+
videoSourceType: string = ''
117128
videoSearchWord: string = ''
118-
videoSearchResult: formData[] = []
129+
videoSearchResult: (formData | undefined)[] = []
119130
page: number = 1
120131
pageSize: number = 5
121132
length: number = 0
122-
displayLists: formData[] = []
133+
displayLists: (formData | undefined)[] = []
123134
124135
mounted() {
125-
fetch('/data/movies.json')
126-
.then((res) => res.json())
127-
.then((data) => {
128-
movies = data
129-
})
136+
// fetch('/data/movies.json')
137+
// .then((res) => res.json())
138+
// .then((data) => {
139+
// movies = data
140+
// })
130141
}
131142
132143
private get form(): formData {
@@ -147,6 +158,15 @@ export default class EditLessonScreenInner3 extends Vue {
147158
this.tempFormData = this.value
148159
}
149160
161+
private handleChangeMovie(selected: MovieListItem) {
162+
this.videoSourceType = selected.sourceType
163+
fetch(`/data/${selected.dataFile}`)
164+
.then((res) => res.json())
165+
.then((data) => {
166+
movies = data
167+
})
168+
}
169+
150170
private handleVideoSearchWord() {
151171
if (this.videoSearchWord) {
152172
this.page = 1
@@ -158,33 +178,16 @@ export default class EditLessonScreenInner3 extends Vue {
158178
return fullText.includes(this.videoSearchWord)
159179
})
160180
.map((v) => {
161-
const videoId = v['教材_ID']
162-
const videoType = parseInt(videoId.slice(5, 6))
163-
const nfsMovieUrl = 'https://www2.nhk.or.jp/school/movie/'
164-
const videoDirectory = videoId.slice(0, 8)
165-
let videoThumbnailUrl = `https://www.nhk.or.jp/das/image/${videoDirectory}/${videoId}_S_005.jpg`
166-
let videoUrl
167-
switch (videoType) {
168-
case 1:
169-
case 2:
170-
videoUrl = `${nfsMovieUrl}bangumi.cgi?das_id=${videoId}&p=box`
181+
let videoInfo
182+
switch (this.videoSourceType) {
183+
case 'NHK':
184+
videoInfo = this.mapNhk(v)
171185
break
172-
case 3:
173-
case 4:
174-
videoUrl = `${nfsMovieUrl}clip.cgi?das_id=${videoId}&p=box`
186+
case 'junyiacademy':
187+
videoInfo = this.mapJunyiacademy(v)
175188
break
176-
default:
177-
videoUrl = null
178-
videoThumbnailUrl = ''
179-
}
180-
return {
181-
videoUrl,
182-
videoTitle: v['教材_タイトル'],
183-
videoSubTitle: v['教材_サブタイトル'],
184-
videoDescription: v['教材_説明'],
185-
videoPlayTime: v['教材_再生時間'],
186-
videoThumbnailUrl,
187189
}
190+
return videoInfo
188191
})
189192
190193
this.length = Math.ceil(this.videoSearchResult.length / this.pageSize)
@@ -193,8 +196,10 @@ export default class EditLessonScreenInner3 extends Vue {
193196
}
194197
}
195198
196-
private registerVideoUrl(url: string) {
199+
private registerVideoUrl(url: string, title: string, thumbnailUrl: string) {
197200
this.tempFormData.videoUrl = url
201+
this.tempFormData.videoTitle = title
202+
this.tempFormData.videoThumbnailUrl = thumbnailUrl
198203
}
199204
200205
private pageChange(pageNumber: number) {
@@ -204,6 +209,48 @@ export default class EditLessonScreenInner3 extends Vue {
204209
)
205210
}
206211
212+
private mapNhk(v: Movie): formData {
213+
const videoId = v.inherentProperties.教材_ID
214+
const videoType = parseInt(videoId.slice(5, 6))
215+
const nfsMovieUrl = 'https://www2.nhk.or.jp/school/movie/'
216+
const videoDirectory = videoId.slice(0, 8)
217+
let videoThumbnailUrl = `https://www.nhk.or.jp/das/image/${videoDirectory}/${videoId}_S_005.jpg`
218+
let videoUrl
219+
switch (videoType) {
220+
case 1:
221+
case 2:
222+
videoUrl = `${nfsMovieUrl}bangumi.cgi?das_id=${videoId}&p=box`
223+
break
224+
case 3:
225+
case 4:
226+
videoUrl = `${nfsMovieUrl}clip.cgi?das_id=${videoId}&p=box`
227+
break
228+
default:
229+
videoUrl = null
230+
videoThumbnailUrl = ''
231+
}
232+
return {
233+
videoUrl,
234+
videoTitle: v.title,
235+
videoSubTitle: v.inherentProperties.教材_サブタイトル,
236+
videoDescription: v.description,
237+
videoPlayTime: v.inherentProperties.教材_再生時間,
238+
videoThumbnailUrl,
239+
}
240+
}
241+
242+
private mapJunyiacademy(v: Movie): formData {
243+
const videoId: string = v.inherentProperties.url.slice(-11)
244+
return {
245+
videoUrl: v.inherentProperties.url,
246+
videoTitle: v.title,
247+
videoSubTitle: '',
248+
videoDescription: v.description,
249+
videoPlayTime: '',
250+
videoThumbnailUrl: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,
251+
}
252+
}
253+
207254
/* CORS 回避必須
208255
@Watch('form.videoUrl')
209256
onChangeVideoUrl() {

src/components/EditorInputFieldPickable.vue

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<template>
22
<div>
33
<span v-if="title" class="EditorField-Title">{{ title }}</span>
4+
<movie-selector
5+
v-if="selector"
6+
class="EditorField-Selector"
7+
@change="$emit('changeMovie', $event)"
8+
/>
49
<div class="EditorField-Form">
510
<editor-input-field
611
:value="value"
@@ -25,9 +30,10 @@
2530
import Vue from 'vue'
2631
import EditorInputField from '@/components/EditorInputField.vue'
2732
import BaseEditorButton from '@/components/BaseEditorButton.vue'
33+
import MovieSelector from '@/components/MovieSelector.vue'
2834
2935
export default Vue.extend({
30-
components: { EditorInputField, BaseEditorButton },
36+
components: { EditorInputField, BaseEditorButton, MovieSelector },
3137
props: {
3238
title: {
3339
type: String,
@@ -69,18 +75,27 @@ export default Vue.extend({
6975
required: false,
7076
default: '',
7177
},
78+
selector: {
79+
type: String,
80+
required: false,
81+
default: '',
82+
},
7283
},
7384
})
7485
</script>
7586

7687
<style lang="scss" scoped>
7788
.EditorField-Title {
78-
display: block;
89+
display: inline-flex;
7990
font-size: 16px;
8091
font-weight: bold;
8192
color: $color-white;
8293
margin-bottom: 4px;
8394
}
95+
.EditorField-Selector {
96+
display: inline-flex;
97+
margin-bottom: 8px;
98+
}
8499
.EditorField-Form {
85100
display: flex;
86101

src/components/MovieSelector.vue

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<template>
2+
<div class="MovieSelector">
3+
<v-select
4+
v-model="selectedMovie"
5+
:items="movies"
6+
item-text="name"
7+
item-value="sourceType"
8+
return-object
9+
class="MovieSelector"
10+
dense
11+
hide-details
12+
solo
13+
@change="$emit('change', $event)"
14+
/>
15+
</div>
16+
</template>
17+
18+
<script lang="ts">
19+
import Vue from 'vue'
20+
21+
import { MovieListItem } from '~/types/movies'
22+
type LocalData = {
23+
selectedMovie: string
24+
movies: MovieListItem[]
25+
}
26+
27+
export default Vue.extend({
28+
data(): LocalData {
29+
return {
30+
selectedMovie: '',
31+
movies: [],
32+
}
33+
},
34+
mounted() {
35+
this.selectedMovie =
36+
this.$root.$i18n.locale === 'zh-tw' ? 'junyiacademy' : 'NHK'
37+
fetch('/data/movie-source.json')
38+
.then((res) => res.json())
39+
.then((data) => {
40+
this.movies = data
41+
this.$emit(
42+
'change',
43+
this.movies.find((m) => m.sourceType === this.selectedMovie)
44+
)
45+
})
46+
},
47+
})
48+
</script>

src/static/data/movie-source.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"sourceType": "NHK",
4+
"name": "NHK For Schoolの動画",
5+
"dataFile": "movies-nhk.json"
6+
},
7+
{
8+
"sourceType": "junyiacademy",
9+
"name": "均一教育平台 junyiacademy",
10+
"dataFile": "movies-junyiacademy.json"
11+
}
12+
]

0 commit comments

Comments
 (0)