@internetarchive/radio-player 0.0.4-alpha.1 → 0.1.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -661
- package/README.md +142 -142
- package/index.d.ts +15 -15
- package/index.js +28 -28
- package/lib/src/assets/img/left.d.ts +2 -2
- package/lib/src/assets/img/left.js +15 -15
- package/lib/src/assets/img/right.d.ts +2 -2
- package/lib/src/assets/img/right.js +15 -15
- package/lib/src/models/music-zone.d.ts +12 -12
- package/lib/src/models/music-zone.js +15 -15
- package/lib/src/models/radio-player-config.d.ts +26 -26
- package/lib/src/models/radio-player-config.js +27 -27
- package/lib/src/radio-player.d.ts +589 -589
- package/lib/src/radio-player.js +1337 -1338
- package/lib/src/radio-player.js.map +1 -1
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-backend.d.ts +82 -82
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-backend.js +107 -107
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-delegate.d.ts +9 -0
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-delegate.js +1 -0
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-delegate.js.map +1 -0
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-response.d.ts +48 -48
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-response.js +58 -58
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-service-interface.d.ts +16 -16
- package/lib/src/search-handler/search-backends/full-text-search-backend/full-text-search-service-interface.js +1 -1
- package/lib/src/search-handler/search-backends/local-search-backend/local-search-backend.d.ts +27 -27
- package/lib/src/search-handler/search-backends/local-search-backend/local-search-backend.js +42 -42
- package/lib/src/search-handler/search-backends/search-backend-interface.d.ts +9 -9
- package/lib/src/search-handler/search-backends/search-backend-interface.js +1 -1
- package/lib/src/search-handler/search-handler-interface.d.ts +17 -17
- package/lib/src/search-handler/search-handler-interface.js +1 -1
- package/lib/src/search-handler/search-handler.d.ts +83 -83
- package/lib/src/search-handler/search-handler.js +177 -177
- package/lib/src/search-handler/search-helper.d.ts +12 -12
- package/lib/src/search-handler/search-helper.js +22 -22
- package/lib/src/search-handler/search-index.d.ts +53 -0
- package/lib/src/search-handler/search-index.js +118 -0
- package/lib/src/search-handler/search-index.js.map +1 -0
- package/lib/src/search-handler/search-models.d.ts +45 -45
- package/lib/src/search-handler/search-models.js +49 -49
- package/lib/src/search-handler/transcript-index-interface.d.ts +38 -38
- package/lib/src/search-handler/transcript-index-interface.js +1 -1
- package/lib/src/search-handler/transcript-index.d.ts +53 -53
- package/lib/src/search-handler/transcript-index.js +80 -80
- package/lib/src/search-results-switcher.d.ts +58 -58
- package/lib/src/search-results-switcher.js +133 -133
- package/package.json +93 -93
- package/src/assets/img/left.ts +17 -17
- package/src/assets/img/right.ts +17 -17
- package/src/models/music-zone.ts +17 -17
- package/src/models/radio-player-config.ts +47 -47
- package/src/radio-player.ts +1398 -1402
- package/src/search-handler/search-backends/full-text-search-backend/full-text-search-backend.ts +140 -140
- package/src/search-handler/search-backends/full-text-search-backend/full-text-search-response.ts +110 -110
- package/src/search-handler/search-backends/full-text-search-backend/full-text-search-service-interface.ts +17 -17
- package/src/search-handler/search-backends/local-search-backend/local-search-backend.ts +50 -50
- package/src/search-handler/search-backends/search-backend-interface.ts +10 -10
- package/src/search-handler/search-handler-interface.ts +18 -18
- package/src/search-handler/search-handler.ts +217 -217
- package/src/search-handler/search-helper.ts +25 -25
- package/src/search-handler/search-models.ts +69 -69
- package/src/search-handler/transcript-index-interface.ts +42 -42
- package/src/search-handler/transcript-index.ts +93 -93
- package/src/search-results-switcher.ts +131 -131
- package/lib/demo/full-text-search-service.d.ts +0 -14
- package/lib/demo/full-text-search-service.js +0 -34
- package/lib/demo/full-text-search-service.js.map +0 -1
- package/lib/demo/radio-player-controller.d.ts +0 -41
- package/lib/demo/radio-player-controller.js +0 -200
- package/lib/demo/radio-player-controller.js.map +0 -1
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import { TranscriptEntryRange } from './search-models';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The TranscriptIndexInterface defines methods needed to access and rebuild the transcript.
|
|
5
|
-
*
|
|
6
|
-
* @export
|
|
7
|
-
* @interface TranscriptIndexInterface
|
|
8
|
-
*/
|
|
9
|
-
export interface TranscriptIndexInterface {
|
|
10
|
-
/**
|
|
11
|
-
* The merged transcript, combining all entries with a single space
|
|
12
|
-
*
|
|
13
|
-
* @type {string}
|
|
14
|
-
* @memberof TranscriptIndexInterface
|
|
15
|
-
*/
|
|
16
|
-
mergedTranscript: string;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* The merged transcript lowercased for case-insensitive lookups
|
|
20
|
-
*
|
|
21
|
-
* @type {string}
|
|
22
|
-
* @memberof TranscriptIndexInterface
|
|
23
|
-
*/
|
|
24
|
-
mergedTranscriptLowercased: string;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* An array of transcript entries with their associated character ranges
|
|
28
|
-
*
|
|
29
|
-
* @type {TranscriptEntryRange[]}
|
|
30
|
-
* @memberof TranscriptIndexInterface
|
|
31
|
-
*/
|
|
32
|
-
transcriptEntryRanges: TranscriptEntryRange[];
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Get the TranscriptEntryRange at a given index
|
|
36
|
-
*
|
|
37
|
-
* @param {number} overallCharIndex
|
|
38
|
-
* @returns {(TranscriptEntryRange | undefined)}
|
|
39
|
-
* @memberof TranscriptIndexInterface
|
|
40
|
-
*/
|
|
41
|
-
getTranscriptEntryAt(overallCharIndex: number): TranscriptEntryRange | undefined;
|
|
42
|
-
}
|
|
1
|
+
import { TranscriptEntryRange } from './search-models';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The TranscriptIndexInterface defines methods needed to access and rebuild the transcript.
|
|
5
|
+
*
|
|
6
|
+
* @export
|
|
7
|
+
* @interface TranscriptIndexInterface
|
|
8
|
+
*/
|
|
9
|
+
export interface TranscriptIndexInterface {
|
|
10
|
+
/**
|
|
11
|
+
* The merged transcript, combining all entries with a single space
|
|
12
|
+
*
|
|
13
|
+
* @type {string}
|
|
14
|
+
* @memberof TranscriptIndexInterface
|
|
15
|
+
*/
|
|
16
|
+
mergedTranscript: string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The merged transcript lowercased for case-insensitive lookups
|
|
20
|
+
*
|
|
21
|
+
* @type {string}
|
|
22
|
+
* @memberof TranscriptIndexInterface
|
|
23
|
+
*/
|
|
24
|
+
mergedTranscriptLowercased: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* An array of transcript entries with their associated character ranges
|
|
28
|
+
*
|
|
29
|
+
* @type {TranscriptEntryRange[]}
|
|
30
|
+
* @memberof TranscriptIndexInterface
|
|
31
|
+
*/
|
|
32
|
+
transcriptEntryRanges: TranscriptEntryRange[];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get the TranscriptEntryRange at a given index
|
|
36
|
+
*
|
|
37
|
+
* @param {number} overallCharIndex
|
|
38
|
+
* @returns {(TranscriptEntryRange | undefined)}
|
|
39
|
+
* @memberof TranscriptIndexInterface
|
|
40
|
+
*/
|
|
41
|
+
getTranscriptEntryAt(overallCharIndex: number): TranscriptEntryRange | undefined;
|
|
42
|
+
}
|
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import { TranscriptConfig, TranscriptEntryConfig } from '@internetarchive/transcript-view';
|
|
2
|
-
import { Range, TranscriptEntryRange } from './search-models';
|
|
3
|
-
import { TranscriptIndexInterface } from './transcript-index-interface';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The TranscriptIndex takes the original transcript and indexes it to make
|
|
7
|
-
* transcript entry lookups more efficient.
|
|
8
|
-
*/
|
|
9
|
-
export class TranscriptIndex implements TranscriptIndexInterface {
|
|
10
|
-
/** @inheritdoc */
|
|
11
|
-
get mergedTranscript(): string {
|
|
12
|
-
return this.mergedTranscriptCache;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** @inheritdoc */
|
|
16
|
-
get mergedTranscriptLowercased(): string {
|
|
17
|
-
return this.mergedTranscriptLowercasedCache;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** @inheritdoc */
|
|
21
|
-
get transcriptEntryRanges(): TranscriptEntryRange[] {
|
|
22
|
-
return this.transcriptEntryRangesCache;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** @inheritdoc */
|
|
26
|
-
getTranscriptEntryAt(overallCharIndex: number): TranscriptEntryRange | undefined {
|
|
27
|
-
return this.transcriptEntryRanges.find((entry) => {
|
|
28
|
-
const { range } = entry;
|
|
29
|
-
return range.endIndex > overallCharIndex && range.startIndex <= overallCharIndex;
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* This gets populated as part of the search index build. It merges all of the transcript
|
|
35
|
-
* entries together so we can search it as a single document instead of a bunch of
|
|
36
|
-
* individual entries. This allows searches to cross over transcript entries.
|
|
37
|
-
*
|
|
38
|
-
* NOTE: When the mergedTranscript gets created, spaces are put between each transcript
|
|
39
|
-
* entry, otherwise the words would run into each other. We account for this in the
|
|
40
|
-
* indices above.
|
|
41
|
-
*
|
|
42
|
-
* @type {string}
|
|
43
|
-
* @memberof TranscriptIndex
|
|
44
|
-
*/
|
|
45
|
-
private mergedTranscriptCache = '';
|
|
46
|
-
|
|
47
|
-
private mergedTranscriptLowercasedCache = '';
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* This gets populated as part of the search index build. It maps the start and end indicies
|
|
51
|
-
* of all of the transcript entries so we can quickly look up where an entry is in the
|
|
52
|
-
* overall transcript.
|
|
53
|
-
*
|
|
54
|
-
* @type {TranscriptEntryRange[]}
|
|
55
|
-
* @memberof TranscriptIndex
|
|
56
|
-
*/
|
|
57
|
-
private transcriptEntryRangesCache: TranscriptEntryRange[] = [];
|
|
58
|
-
|
|
59
|
-
constructor(transcriptConfig: TranscriptConfig) {
|
|
60
|
-
this.buildIndex(transcriptConfig);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Build the search index. This method does two things:
|
|
65
|
-
* 1. Builds the "merged transcript" with all of the text combined into one long transcript.
|
|
66
|
-
* This allows us to search the entire thing at once instead of entry by entry.
|
|
67
|
-
* 2. For each entry, get the start and end index of that particular entry within the overall
|
|
68
|
-
* transcript. This allows us to reconstruct the transcript later from the original transcript
|
|
69
|
-
* and the search results.
|
|
70
|
-
*
|
|
71
|
-
* @private
|
|
72
|
-
* @memberof TranscriptIndex
|
|
73
|
-
*/
|
|
74
|
-
private buildIndex(transcriptConfig: TranscriptConfig): void {
|
|
75
|
-
let startIndex = 0;
|
|
76
|
-
const transcriptEntryRanges: TranscriptEntryRange[] = [];
|
|
77
|
-
let mergedTranscript = '';
|
|
78
|
-
|
|
79
|
-
transcriptConfig.entries.forEach((entry: TranscriptEntryConfig) => {
|
|
80
|
-
const { displayText } = entry;
|
|
81
|
-
const indexMapRange: Range = new Range(startIndex, startIndex + displayText.length);
|
|
82
|
-
const indexMap: TranscriptEntryRange = new TranscriptEntryRange(entry, indexMapRange);
|
|
83
|
-
transcriptEntryRanges.push(indexMap);
|
|
84
|
-
mergedTranscript += `${entry.rawText} `;
|
|
85
|
-
startIndex = mergedTranscript.length;
|
|
86
|
-
});
|
|
87
|
-
mergedTranscript = mergedTranscript.trim();
|
|
88
|
-
|
|
89
|
-
this.mergedTranscriptCache = mergedTranscript;
|
|
90
|
-
this.mergedTranscriptLowercasedCache = mergedTranscript.toLowerCase();
|
|
91
|
-
this.transcriptEntryRangesCache = transcriptEntryRanges;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
1
|
+
import { TranscriptConfig, TranscriptEntryConfig } from '@internetarchive/transcript-view';
|
|
2
|
+
import { Range, TranscriptEntryRange } from './search-models';
|
|
3
|
+
import { TranscriptIndexInterface } from './transcript-index-interface';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The TranscriptIndex takes the original transcript and indexes it to make
|
|
7
|
+
* transcript entry lookups more efficient.
|
|
8
|
+
*/
|
|
9
|
+
export class TranscriptIndex implements TranscriptIndexInterface {
|
|
10
|
+
/** @inheritdoc */
|
|
11
|
+
get mergedTranscript(): string {
|
|
12
|
+
return this.mergedTranscriptCache;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** @inheritdoc */
|
|
16
|
+
get mergedTranscriptLowercased(): string {
|
|
17
|
+
return this.mergedTranscriptLowercasedCache;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** @inheritdoc */
|
|
21
|
+
get transcriptEntryRanges(): TranscriptEntryRange[] {
|
|
22
|
+
return this.transcriptEntryRangesCache;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** @inheritdoc */
|
|
26
|
+
getTranscriptEntryAt(overallCharIndex: number): TranscriptEntryRange | undefined {
|
|
27
|
+
return this.transcriptEntryRanges.find((entry) => {
|
|
28
|
+
const { range } = entry;
|
|
29
|
+
return range.endIndex > overallCharIndex && range.startIndex <= overallCharIndex;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* This gets populated as part of the search index build. It merges all of the transcript
|
|
35
|
+
* entries together so we can search it as a single document instead of a bunch of
|
|
36
|
+
* individual entries. This allows searches to cross over transcript entries.
|
|
37
|
+
*
|
|
38
|
+
* NOTE: When the mergedTranscript gets created, spaces are put between each transcript
|
|
39
|
+
* entry, otherwise the words would run into each other. We account for this in the
|
|
40
|
+
* indices above.
|
|
41
|
+
*
|
|
42
|
+
* @type {string}
|
|
43
|
+
* @memberof TranscriptIndex
|
|
44
|
+
*/
|
|
45
|
+
private mergedTranscriptCache = '';
|
|
46
|
+
|
|
47
|
+
private mergedTranscriptLowercasedCache = '';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* This gets populated as part of the search index build. It maps the start and end indicies
|
|
51
|
+
* of all of the transcript entries so we can quickly look up where an entry is in the
|
|
52
|
+
* overall transcript.
|
|
53
|
+
*
|
|
54
|
+
* @type {TranscriptEntryRange[]}
|
|
55
|
+
* @memberof TranscriptIndex
|
|
56
|
+
*/
|
|
57
|
+
private transcriptEntryRangesCache: TranscriptEntryRange[] = [];
|
|
58
|
+
|
|
59
|
+
constructor(transcriptConfig: TranscriptConfig) {
|
|
60
|
+
this.buildIndex(transcriptConfig);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Build the search index. This method does two things:
|
|
65
|
+
* 1. Builds the "merged transcript" with all of the text combined into one long transcript.
|
|
66
|
+
* This allows us to search the entire thing at once instead of entry by entry.
|
|
67
|
+
* 2. For each entry, get the start and end index of that particular entry within the overall
|
|
68
|
+
* transcript. This allows us to reconstruct the transcript later from the original transcript
|
|
69
|
+
* and the search results.
|
|
70
|
+
*
|
|
71
|
+
* @private
|
|
72
|
+
* @memberof TranscriptIndex
|
|
73
|
+
*/
|
|
74
|
+
private buildIndex(transcriptConfig: TranscriptConfig): void {
|
|
75
|
+
let startIndex = 0;
|
|
76
|
+
const transcriptEntryRanges: TranscriptEntryRange[] = [];
|
|
77
|
+
let mergedTranscript = '';
|
|
78
|
+
|
|
79
|
+
transcriptConfig.entries.forEach((entry: TranscriptEntryConfig) => {
|
|
80
|
+
const { displayText } = entry;
|
|
81
|
+
const indexMapRange: Range = new Range(startIndex, startIndex + displayText.length);
|
|
82
|
+
const indexMap: TranscriptEntryRange = new TranscriptEntryRange(entry, indexMapRange);
|
|
83
|
+
transcriptEntryRanges.push(indexMap);
|
|
84
|
+
mergedTranscript += `${entry.rawText} `;
|
|
85
|
+
startIndex = mergedTranscript.length;
|
|
86
|
+
});
|
|
87
|
+
mergedTranscript = mergedTranscript.trim();
|
|
88
|
+
|
|
89
|
+
this.mergedTranscriptCache = mergedTranscript;
|
|
90
|
+
this.mergedTranscriptLowercasedCache = mergedTranscript.toLowerCase();
|
|
91
|
+
this.transcriptEntryRangesCache = transcriptEntryRanges;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -1,131 +1,131 @@
|
|
|
1
|
-
import {
|
|
2
|
-
LitElement,
|
|
3
|
-
html,
|
|
4
|
-
css,
|
|
5
|
-
CSSResult,
|
|
6
|
-
TemplateResult,
|
|
7
|
-
PropertyValues,
|
|
8
|
-
} from 'lit';
|
|
9
|
-
import {
|
|
10
|
-
customElement,
|
|
11
|
-
property,
|
|
12
|
-
} from 'lit/decorators.js';
|
|
13
|
-
import leftImage from './assets/img/left';
|
|
14
|
-
import rightImage from './assets/img/right';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* A widget to switch between search results that looks like this:
|
|
18
|
-
* < 3 / 7 >
|
|
19
|
-
*
|
|
20
|
-
* @export
|
|
21
|
-
* @class SearchResultsSwitcher
|
|
22
|
-
* @extends {LitElement}
|
|
23
|
-
*/
|
|
24
|
-
@customElement('search-results-switcher')
|
|
25
|
-
export default class SearchResultsSwitcher extends LitElement {
|
|
26
|
-
@property({ type: Number }) numberOfResults = 0;
|
|
27
|
-
|
|
28
|
-
@property({ type: Number }) currentResultIndex = 0;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* LitElement life cycle render method. Entrypoint for rendering the element.
|
|
32
|
-
*
|
|
33
|
-
* @returns {TemplateResult}
|
|
34
|
-
* @memberof SearchResultsSwitcher
|
|
35
|
-
*/
|
|
36
|
-
render(): TemplateResult {
|
|
37
|
-
return html`
|
|
38
|
-
<div class="container">
|
|
39
|
-
<button @click=${this.goToPreviousResult} id="previous-button">
|
|
40
|
-
${leftImage}
|
|
41
|
-
</button>
|
|
42
|
-
<span class="results-range">
|
|
43
|
-
<span id="current-result">${this.currentResultIndex + 1}</span> /
|
|
44
|
-
<span id="number-of-results">${this.numberOfResults}</span>
|
|
45
|
-
</span>
|
|
46
|
-
<button @click=${this.goToNextResult} id="next-button">
|
|
47
|
-
${rightImage}
|
|
48
|
-
</button>
|
|
49
|
-
</div>
|
|
50
|
-
`;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* LitElement life cycle CSS for this element
|
|
55
|
-
*
|
|
56
|
-
* @readonly
|
|
57
|
-
* @static
|
|
58
|
-
* @type {CSSResult}
|
|
59
|
-
* @memberof SearchResultsSwitcher
|
|
60
|
-
*/
|
|
61
|
-
static get styles(): CSSResult {
|
|
62
|
-
return css`
|
|
63
|
-
.container {
|
|
64
|
-
text-align: center;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
button {
|
|
68
|
-
background: none;
|
|
69
|
-
border: 0;
|
|
70
|
-
cursor: pointer;
|
|
71
|
-
}
|
|
72
|
-
`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* LitElement lifecycle updated method
|
|
77
|
-
*
|
|
78
|
-
* @param {PropertyValues} changedProperties
|
|
79
|
-
* @memberof SearchResultsSwitcher
|
|
80
|
-
*/
|
|
81
|
-
updated(changedProperties: PropertyValues): void {
|
|
82
|
-
// reset the index if we change the number of results
|
|
83
|
-
if (changedProperties.has('numberOfResults')) {
|
|
84
|
-
this.currentResultIndex = 0;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Called when user clicks on the previous result button.
|
|
90
|
-
* Loops around to the last result when we reach the first.
|
|
91
|
-
*
|
|
92
|
-
* @memberof SearchResultsSwitcher
|
|
93
|
-
*/
|
|
94
|
-
goToPreviousResult(): void {
|
|
95
|
-
if (this.currentResultIndex < 1) {
|
|
96
|
-
this.currentResultIndex = this.numberOfResults - 1;
|
|
97
|
-
} else {
|
|
98
|
-
this.currentResultIndex -= 1;
|
|
99
|
-
}
|
|
100
|
-
this.emitSearchResultIndexChangedEvent();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Called when user clicks on the next result button.
|
|
105
|
-
* Loops around to the first result when we reach the last.
|
|
106
|
-
*
|
|
107
|
-
* @memberof SearchResultsSwitcher
|
|
108
|
-
*/
|
|
109
|
-
goToNextResult(): void {
|
|
110
|
-
if (this.currentResultIndex === this.numberOfResults - 1) {
|
|
111
|
-
this.currentResultIndex = 0;
|
|
112
|
-
} else {
|
|
113
|
-
this.currentResultIndex += 1;
|
|
114
|
-
}
|
|
115
|
-
this.emitSearchResultIndexChangedEvent();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Emit an searchResultIndexChanged event that the index has been changed
|
|
120
|
-
*
|
|
121
|
-
* ie: `e.detail.searchResultIndex = 2`
|
|
122
|
-
*
|
|
123
|
-
* @memberof SearchResultsSwitcher
|
|
124
|
-
*/
|
|
125
|
-
emitSearchResultIndexChangedEvent(): void {
|
|
126
|
-
const event = new CustomEvent('searchResultIndexChanged', {
|
|
127
|
-
detail: { searchResultIndex: this.currentResultIndex },
|
|
128
|
-
});
|
|
129
|
-
this.dispatchEvent(event);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
LitElement,
|
|
3
|
+
html,
|
|
4
|
+
css,
|
|
5
|
+
CSSResult,
|
|
6
|
+
TemplateResult,
|
|
7
|
+
PropertyValues,
|
|
8
|
+
} from 'lit';
|
|
9
|
+
import {
|
|
10
|
+
customElement,
|
|
11
|
+
property,
|
|
12
|
+
} from 'lit/decorators.js';
|
|
13
|
+
import leftImage from './assets/img/left';
|
|
14
|
+
import rightImage from './assets/img/right';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A widget to switch between search results that looks like this:
|
|
18
|
+
* < 3 / 7 >
|
|
19
|
+
*
|
|
20
|
+
* @export
|
|
21
|
+
* @class SearchResultsSwitcher
|
|
22
|
+
* @extends {LitElement}
|
|
23
|
+
*/
|
|
24
|
+
@customElement('search-results-switcher')
|
|
25
|
+
export default class SearchResultsSwitcher extends LitElement {
|
|
26
|
+
@property({ type: Number }) numberOfResults = 0;
|
|
27
|
+
|
|
28
|
+
@property({ type: Number }) currentResultIndex = 0;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* LitElement life cycle render method. Entrypoint for rendering the element.
|
|
32
|
+
*
|
|
33
|
+
* @returns {TemplateResult}
|
|
34
|
+
* @memberof SearchResultsSwitcher
|
|
35
|
+
*/
|
|
36
|
+
render(): TemplateResult {
|
|
37
|
+
return html`
|
|
38
|
+
<div class="container">
|
|
39
|
+
<button @click=${this.goToPreviousResult} id="previous-button">
|
|
40
|
+
${leftImage}
|
|
41
|
+
</button>
|
|
42
|
+
<span class="results-range">
|
|
43
|
+
<span id="current-result">${this.currentResultIndex + 1}</span> /
|
|
44
|
+
<span id="number-of-results">${this.numberOfResults}</span>
|
|
45
|
+
</span>
|
|
46
|
+
<button @click=${this.goToNextResult} id="next-button">
|
|
47
|
+
${rightImage}
|
|
48
|
+
</button>
|
|
49
|
+
</div>
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* LitElement life cycle CSS for this element
|
|
55
|
+
*
|
|
56
|
+
* @readonly
|
|
57
|
+
* @static
|
|
58
|
+
* @type {CSSResult}
|
|
59
|
+
* @memberof SearchResultsSwitcher
|
|
60
|
+
*/
|
|
61
|
+
static get styles(): CSSResult {
|
|
62
|
+
return css`
|
|
63
|
+
.container {
|
|
64
|
+
text-align: center;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
button {
|
|
68
|
+
background: none;
|
|
69
|
+
border: 0;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* LitElement lifecycle updated method
|
|
77
|
+
*
|
|
78
|
+
* @param {PropertyValues} changedProperties
|
|
79
|
+
* @memberof SearchResultsSwitcher
|
|
80
|
+
*/
|
|
81
|
+
updated(changedProperties: PropertyValues): void {
|
|
82
|
+
// reset the index if we change the number of results
|
|
83
|
+
if (changedProperties.has('numberOfResults')) {
|
|
84
|
+
this.currentResultIndex = 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Called when user clicks on the previous result button.
|
|
90
|
+
* Loops around to the last result when we reach the first.
|
|
91
|
+
*
|
|
92
|
+
* @memberof SearchResultsSwitcher
|
|
93
|
+
*/
|
|
94
|
+
goToPreviousResult(): void {
|
|
95
|
+
if (this.currentResultIndex < 1) {
|
|
96
|
+
this.currentResultIndex = this.numberOfResults - 1;
|
|
97
|
+
} else {
|
|
98
|
+
this.currentResultIndex -= 1;
|
|
99
|
+
}
|
|
100
|
+
this.emitSearchResultIndexChangedEvent();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Called when user clicks on the next result button.
|
|
105
|
+
* Loops around to the first result when we reach the last.
|
|
106
|
+
*
|
|
107
|
+
* @memberof SearchResultsSwitcher
|
|
108
|
+
*/
|
|
109
|
+
goToNextResult(): void {
|
|
110
|
+
if (this.currentResultIndex === this.numberOfResults - 1) {
|
|
111
|
+
this.currentResultIndex = 0;
|
|
112
|
+
} else {
|
|
113
|
+
this.currentResultIndex += 1;
|
|
114
|
+
}
|
|
115
|
+
this.emitSearchResultIndexChangedEvent();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Emit an searchResultIndexChanged event that the index has been changed
|
|
120
|
+
*
|
|
121
|
+
* ie: `e.detail.searchResultIndex = 2`
|
|
122
|
+
*
|
|
123
|
+
* @memberof SearchResultsSwitcher
|
|
124
|
+
*/
|
|
125
|
+
emitSearchResultIndexChangedEvent(): void {
|
|
126
|
+
const event = new CustomEvent('searchResultIndexChanged', {
|
|
127
|
+
detail: { searchResultIndex: this.currentResultIndex },
|
|
128
|
+
});
|
|
129
|
+
this.dispatchEvent(event);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { FullTextSearchServiceInterface } from '../src/search-handler/search-backends/full-text-search-backend/full-text-search-service-interface';
|
|
2
|
-
import { FullTextSearchResponse } from '../src/search-handler/search-backends/full-text-search-backend/full-text-search-response';
|
|
3
|
-
/**
|
|
4
|
-
* An example FullTextSearchService that fetches data from the backend and
|
|
5
|
-
* returns a Promise<FullTextSearch> response.
|
|
6
|
-
*/
|
|
7
|
-
export declare class FullTextSearchService implements FullTextSearchServiceInterface {
|
|
8
|
-
private itemId;
|
|
9
|
-
private baseUrl;
|
|
10
|
-
private searchServicePath;
|
|
11
|
-
constructor(itemId: string, baseUrl: string, searchServicePath: string);
|
|
12
|
-
/** @inheritdoc */
|
|
13
|
-
searchRequested(query: string): Promise<FullTextSearchResponse>;
|
|
14
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import { FullTextSearchResponse } from '../src/search-handler/search-backends/full-text-search-backend/full-text-search-response';
|
|
11
|
-
/**
|
|
12
|
-
* An example FullTextSearchService that fetches data from the backend and
|
|
13
|
-
* returns a Promise<FullTextSearch> response.
|
|
14
|
-
*/
|
|
15
|
-
export class FullTextSearchService {
|
|
16
|
-
constructor(itemId, baseUrl, searchServicePath) {
|
|
17
|
-
this.itemId = itemId;
|
|
18
|
-
this.baseUrl = baseUrl;
|
|
19
|
-
this.searchServicePath = searchServicePath;
|
|
20
|
-
}
|
|
21
|
-
/** @inheritdoc */
|
|
22
|
-
searchRequested(query) {
|
|
23
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
-
const searchUrl = `${this.baseUrl}${this.searchServicePath}`;
|
|
25
|
-
const queryParams = `?q=${query}&identifier=${this.itemId}&number_of_fragments=1000&scope=all`;
|
|
26
|
-
const url = `${searchUrl}${queryParams}`;
|
|
27
|
-
const rawResponse = yield fetch(url);
|
|
28
|
-
const jsonResponse = yield rawResponse.json();
|
|
29
|
-
const modeledResponse = new FullTextSearchResponse(jsonResponse);
|
|
30
|
-
return new Promise(resolve => resolve(modeledResponse));
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=full-text-search-service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"full-text-search-service.js","sourceRoot":"","sources":["../../demo/full-text-search-service.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0FAA0F,CAAC;AAElI;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IAOhC,YAAY,MAAc,EAAE,OAAe,EAAE,iBAAyB;QACpE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC7C,CAAC;IAED,kBAAkB;IACZ,eAAe,CAAC,KAAa;;YACjC,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC7D,MAAM,WAAW,GAAG,MAAM,KAAK,eAAe,IAAI,CAAC,MAAM,qCAAqC,CAAC;YAC/F,MAAM,GAAG,GAAG,GAAG,SAAS,GAAG,WAAW,EAAE,CAAC;YACzC,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YACrC,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;YAC9C,MAAM,eAAe,GAAG,IAAI,sBAAsB,CAAC,YAAY,CAAC,CAAC;YAEjE,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;QAC1D,CAAC;KAAA;CACF"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { LitElement, TemplateResult, PropertyValues } from 'lit';
|
|
2
|
-
import { TranscriptConfig } from '@internetarchive/transcript-view';
|
|
3
|
-
import '../src/radio-player';
|
|
4
|
-
import RadioPlayerConfig from '../src/models/radio-player-config';
|
|
5
|
-
import { SearchHandlerInterface } from '../src/search-handler/search-handler-interface';
|
|
6
|
-
export default class RadioPlayerController extends LitElement {
|
|
7
|
-
radioPlayerConfig: RadioPlayerConfig | undefined;
|
|
8
|
-
transcriptConfig: TranscriptConfig | undefined;
|
|
9
|
-
itemId: string | undefined;
|
|
10
|
-
/**
|
|
11
|
-
* The Search Handler
|
|
12
|
-
*
|
|
13
|
-
* @type {(SearchHandlerInterface | undefined)}
|
|
14
|
-
* @memberof RadioPlayer
|
|
15
|
-
*/
|
|
16
|
-
searchHandler: SearchHandlerInterface | undefined;
|
|
17
|
-
private startPlaybackAt;
|
|
18
|
-
private currentTime;
|
|
19
|
-
private fileName;
|
|
20
|
-
private baseUrl;
|
|
21
|
-
private searchServicePath;
|
|
22
|
-
private searchBackend;
|
|
23
|
-
private searchService;
|
|
24
|
-
render(): TemplateResult;
|
|
25
|
-
loadItemMetadata(): Promise<any>;
|
|
26
|
-
fetchTranscript(): Promise<any>;
|
|
27
|
-
setup(): Promise<any>;
|
|
28
|
-
handleMetadataResponse(response: any): void;
|
|
29
|
-
private get radioPlayer();
|
|
30
|
-
firstUpdated(): void;
|
|
31
|
-
updated(changedProperties: PropertyValues): void;
|
|
32
|
-
private setupSearchHandler;
|
|
33
|
-
private canplay;
|
|
34
|
-
private searchTermChanged;
|
|
35
|
-
private currentTimeChanged;
|
|
36
|
-
private playbackPaused;
|
|
37
|
-
private timeChangedFromScrub;
|
|
38
|
-
private transcriptEntrySelected;
|
|
39
|
-
private updateStartTimeQueryParam;
|
|
40
|
-
private updateSearchQueryParam;
|
|
41
|
-
}
|