Skip to content

Commit

Permalink
Add basic media overlay support
Browse files Browse the repository at this point in the history
  • Loading branch information
johnfactotum committed Oct 5, 2023
1 parent 383d3c4 commit 0a34301
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 5 deletions.
13 changes: 13 additions & 0 deletions src/book-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ GObject.registerClass({
enable_html5_database: false,
enable_html5_local_storage: false,
}),
// needed for playing media overlay
website_policies: new WebKit.WebsitePolicies({
autoplay: WebKit.AutoplayPolicy.ALLOW,
}),
}), {
'run-file-chooser': (_, req) =>
(req.select_files([encodeURI(this.#path)]), true),
Expand Down Expand Up @@ -581,6 +585,9 @@ GObject.registerClass({
ttsNext(x) { return this.#exec('reader.view.tts.next', x) }
ttsResume() { return this.#exec('reader.view.tts.resume') }
ttsSetMark(x) { return this.#exec('reader.view.tts.setMark', x) }
mediaOverlayStart() { return this.#exec('reader.view.startMediaOverlay') }
mediaOverlayPause() { return this.#exec('reader.view.mediaOverlay.pause') }
mediaOverlayResume() { return this.#exec('reader.view.mediaOverlay.resume') }
getCover() { return this.#exec('reader.getCover').then(utils.base64ToPixbuf) }
init(x) { return this.#exec('reader.view.init', x) }
get webView() { return this.#webView }
Expand Down Expand Up @@ -825,6 +832,11 @@ export const BookViewer = GObject.registerClass({
// FIXME: check if at end
'next-section': () => this._view.next().then(() => true),
})
utils.connect(this._navbar.media_overlay_box, {
'start': () => this._view.mediaOverlayStart(),
'pause': () => this._view.mediaOverlayPause(),
'resume': () => this._view.mediaOverlayResume(),
})

// setup actions
const actions = utils.addMethods(this, {
Expand Down Expand Up @@ -923,6 +935,7 @@ export const BookViewer = GObject.registerClass({
this._navbar.loadSections(book.sections)
this._navbar.loadPageList(book.pageList, reader.pageTotal)
this._navbar.loadLandmarks(book.landmarks)
this._navbar.setTTSType(book.media.duration ? 'media-overlay' : 'tts')

const cover = await this._view.getCover()
this.#cover = cover
Expand Down
2 changes: 1 addition & 1 deletion src/foliate-js
Submodule foliate-js updated 5 files
+18 −0 README.md
+129 −26 epub.js
+43 −0 text-walker.js
+5 −47 tts.js
+28 −25 view.js
3 changes: 3 additions & 0 deletions src/gresource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<file>ui/image-viewer.ui</file>
<file>ui/library.ui</file>
<file>ui/library-view.ui</file>
<file>ui/media-overlay-box.ui</file>
<file>ui/navbar.ui</file>
<file>ui/selection-popover.ui</file>
<file>ui/tts-box.ui</file>
Expand All @@ -44,6 +45,8 @@
<file>foliate-js/paginator.js</file>
<file>foliate-js/progress.js</file>
<file>foliate-js/search.js</file>
<file>foliate-js/text-walker.js</file>
<file>foliate-js/tts.js</file>
<file>foliate-js/view.js</file>
<file>foliate-js/vendor/zip.js</file>
<file>foliate-js/vendor/fflate.js</file>
Expand Down
7 changes: 5 additions & 2 deletions src/navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ GObject.registerClass({
GObject.registerClass({
GTypeName: 'FoliateNavBar',
Template: pkg.moduleuri('ui/navbar.ui'),
Children: ['tts-box'],
Children: ['tts-box', 'media-overlay-box'],
InternalChildren: [
'prev-image', 'next-image', 'back-image', 'forward-image',
'progress-box', 'progress-scale', 'location-button',
'location-popover', 'tts-popover',
'location-popover', 'tts-popover', 'tts-stack',
'time-book', 'time-section',
'page-label', 'page-box', 'page-drop-down', 'page-total',
'loc-entry', 'loc-total', 'cfi-entry',
Expand Down Expand Up @@ -235,4 +235,7 @@ GObject.registerClass({
this.emit('opened')
this._location_button.popup()
}
setTTSType(name) {
this._tts_stack.visible_child_name = name
}
})
48 changes: 47 additions & 1 deletion src/tts.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SSIPClient } from './speech.js'

const ssip = new SSIPClient()

export const TTSBox = GObject.registerClass({
GObject.registerClass({
GTypeName: 'FoliateTTSBox',
Template: pkg.moduleuri('ui/tts-box.ui'),
Signals: {
Expand Down Expand Up @@ -119,3 +119,49 @@ export const TTSBox = GObject.registerClass({
if (this.state === 'playing') ssip.stop().catch(e => console.error(e))
}
})


GObject.registerClass({
GTypeName: 'FoliateMediaOverlayBox',
Template: pkg.moduleuri('ui/media-overlay-box.ui'),
Signals: {
'start': {},
'pause': {},
'resume': {},
},
InternalChildren: [
'tts-rate-scale',
'media-buttons', 'play-button',
],
}, class extends Gtk.Box {
#state = 'stopped'
constructor(params) {
super(params)
this.insert_action_group('media-overlay', utils.addMethods(this, {
actions: ['play', 'backward', 'forward', 'stop'],
}))
utils.setDirection(this._media_buttons, Gtk.TextDirection.LTR)
}
get state() {
return this.#state
}
set state(state) {
this.#state = state
this._play_button.icon_name = state === 'playing'
? 'media-playback-pause-symbolic'
: 'media-playback-start-symbolic'
}
play() {
if (this.#state !== 'playing') this.start()
else this.pause()
}
start() {
if (this.state === 'paused') this.emit('resume')
else this.emit('start')
this.state = 'playing'
}
pause() {
this.state = 'paused'
this.emit('pause')
}
})
95 changes: 95 additions & 0 deletions src/ui/media-overlay-box.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FoliateMediaOverlayBox" parent="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">9</property>
<child>
<object class="GtkGrid">
<property name="column-spacing">6</property>
<property name="row-spacing">9</property>
<property name="margin-start">6</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Speed</property>
<property name="xalign">0</property>
<layout>
<property name="row">1</property>
<property name="column">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="tts-rate-scale">
<property name="draw-value">False</property>
<property name="width-request">200</property>
<property name="hexpand">True</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="lower">-100</property>
<property name="upper">100</property>
<property name="step-increment">5</property>
<property name="page-increment">10</property>
<property name="value">0</property>
</object>
</property>
<marks>
<mark value="0"/>
</marks>
<layout>
<property name="row">1</property>
<property name="column">1</property>
</layout>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkBox" id="media-buttons">
<property name="halign">center</property>
<property name="spacing">12</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<child>
<object class="GtkButton">
<property name="valign">center</property>
<property name="action-name">media-overlay.backward</property>
<property name="tooltip-text" translatable="yes">Previous</property>
<property name="icon-name">media-seek-backward-symbolic</property>
<style><class name="circular"/><class name="flat"/></style>
</object>
</child>
<child>
<object class="GtkToggleButton" id="play-button">
<property name="action-name">media-overlay.play</property>
<property name="tooltip-text" translatable="yes">Play/Pause</property>
<property name="icon-name">media-playback-start-symbolic</property>
<style><class name="circular"/><class name="large-button"/><class name="suggested-action"/></style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="valign">center</property>
<property name="action-name">media-overlay.forward</property>
<property name="tooltip-text" translatable="yes">Next</property>
<property name="icon-name">media-seek-forward-symbolic</property>
<style><class name="circular"/><class name="flat"/></style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="valign">center</property>
<property name="action-name">media-overlay.stop</property>
<property name="tooltip-text" translatable="yes">Stop</property>
<property name="icon-name">media-playback-stop-symbolic</property>
<style><class name="circular"/><class name="flat"/></style>
</object>
</child>
</object>
</child>
</template>
</interface>
22 changes: 21 additions & 1 deletion src/ui/navbar.ui
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,32 @@
<child>
<object class="GtkMenuButton">
<property name="valign">center</property>
<property name="direction">up</property>
<property name="icon-name">audio-headphones-symbolic</property>
<property name="tooltip-text" translatable="yes">Text-to-Speech</property>
<property name="popover">
<object class="GtkPopover" id="tts-popover">
<child>
<object class="FoliateTTSBox" id="tts-box"/>
<object class="GtkStack" id="tts-stack">
<property name="hhomogeneous">False</property>
<property name="vhomogeneous">False</property>
<child>
<object class="GtkStackPage">
<property name="name">tts</property>
<property name="child">
<object class="FoliateTTSBox" id="tts-box"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">media-overlay</property>
<property name="child">
<object class="FoliateMediaOverlayBox" id="media-overlay-box"/>
</property>
</object>
</child>
</object>
</child>
</object>
</property>
Expand Down

0 comments on commit 0a34301

Please sign in to comment.