react-native-readium 1.0.0-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 +21 -0
- package/README.md +135 -0
- package/android/build.gradle +198 -0
- package/android/gradle.properties +3 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/reactnativereadium/ReadiumPackage.kt +17 -0
- package/android/src/main/java/com/reactnativereadium/ReadiumView.kt +84 -0
- package/android/src/main/java/com/reactnativereadium/ReadiumViewManager.kt +80 -0
- package/android/src/main/java/com/reactnativereadium/epub/UserSettings.kt +236 -0
- package/android/src/main/java/com/reactnativereadium/reader/BaseReaderFragment.kt +81 -0
- package/android/src/main/java/com/reactnativereadium/reader/EpubReaderFragment.kt +375 -0
- package/android/src/main/java/com/reactnativereadium/reader/ImageReaderFragment.kt +68 -0
- package/android/src/main/java/com/reactnativereadium/reader/PdfReaderFragment.kt +82 -0
- package/android/src/main/java/com/reactnativereadium/reader/ReaderService.kt +116 -0
- package/android/src/main/java/com/reactnativereadium/reader/ReaderViewModel.kt +120 -0
- package/android/src/main/java/com/reactnativereadium/reader/VisualReaderFragment.kt +78 -0
- package/android/src/main/java/com/reactnativereadium/search/SearchFragment.kt +100 -0
- package/android/src/main/java/com/reactnativereadium/search/SearchPagingSource.kt +44 -0
- package/android/src/main/java/com/reactnativereadium/search/SearchResultAdapter.kt +68 -0
- package/android/src/main/java/com/reactnativereadium/utils/ContentResolverUtil.kt +156 -0
- package/android/src/main/java/com/reactnativereadium/utils/Dimensions.kt +6 -0
- package/android/src/main/java/com/reactnativereadium/utils/EventChannel.kt +61 -0
- package/android/src/main/java/com/reactnativereadium/utils/FragmentFactory.kt +46 -0
- package/android/src/main/java/com/reactnativereadium/utils/R2DispatcherActivity.kt +45 -0
- package/android/src/main/java/com/reactnativereadium/utils/SectionDecoration.kt +98 -0
- package/android/src/main/java/com/reactnativereadium/utils/SingleClickListener.kt +32 -0
- package/android/src/main/java/com/reactnativereadium/utils/SystemUiManagement.kt +63 -0
- package/android/src/main/java/com/reactnativereadium/utils/extensions/Bitmap.kt +23 -0
- package/android/src/main/java/com/reactnativereadium/utils/extensions/Context.kt +16 -0
- package/android/src/main/java/com/reactnativereadium/utils/extensions/File.kt +22 -0
- package/android/src/main/java/com/reactnativereadium/utils/extensions/InputStream.kt +23 -0
- package/android/src/main/java/com/reactnativereadium/utils/extensions/Link.kt +6 -0
- package/android/src/main/java/com/reactnativereadium/utils/extensions/Metadata.kt +6 -0
- package/android/src/main/java/com/reactnativereadium/utils/extensions/URL.kt +29 -0
- package/android/src/main/java/com/reactnativereadium/utils/extensions/Uri.kt +17 -0
- package/android/src/main/res/drawable/background_action_mode.xml +6 -0
- package/android/src/main/res/drawable/cnl.png +0 -0
- package/android/src/main/res/drawable/cover.png +0 -0
- package/android/src/main/res/drawable/ic_add_white_24dp.xml +9 -0
- package/android/src/main/res/drawable/ic_baseline_arrow_forward_24.xml +5 -0
- package/android/src/main/res/drawable/ic_baseline_bookmark_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_delete_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_edit_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_enhanced_encryption_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_fast_forward_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_fast_rewind_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_headphones_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_pause_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_play_arrow_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_search_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_skip_next_24.xml +10 -0
- package/android/src/main/res/drawable/ic_baseline_skip_previous_24.xml +10 -0
- package/android/src/main/res/drawable/ic_dashboard_black_24dp.xml +9 -0
- package/android/src/main/res/drawable/ic_fastforward_30.xml +7 -0
- package/android/src/main/res/drawable/ic_info_black_24dp.xml +9 -0
- package/android/src/main/res/drawable/ic_local_library_black_24dp.xml +9 -0
- package/android/src/main/res/drawable/ic_notch.xml +4 -0
- package/android/src/main/res/drawable/ic_outline_add_24.xml +10 -0
- package/android/src/main/res/drawable/ic_outline_format_align_justify_24.xml +10 -0
- package/android/src/main/res/drawable/ic_outline_format_align_left_24.xml +11 -0
- package/android/src/main/res/drawable/ic_outline_format_size_24.xml +10 -0
- package/android/src/main/res/drawable/ic_outline_light_mode_24.xml +10 -0
- package/android/src/main/res/drawable/ic_outline_menu_24.xml +10 -0
- package/android/src/main/res/drawable/ic_outline_remove_24.xml +10 -0
- package/android/src/main/res/drawable/ic_outline_wb_sunny_24.xml +10 -0
- package/android/src/main/res/drawable/ic_rewind_30.xml +7 -0
- package/android/src/main/res/drawable/icon_font_decrease.png +0 -0
- package/android/src/main/res/drawable/icon_font_increase.png +0 -0
- package/android/src/main/res/drawable/icon_overflow.png +0 -0
- package/android/src/main/res/drawable/rbtn_selector.xml +25 -0
- package/android/src/main/res/drawable/rbtn_textcolor_selector.xml +16 -0
- package/android/src/main/res/drawable/repfr.png +0 -0
- package/android/src/main/res/drawable/selector_blue.xml +42 -0
- package/android/src/main/res/drawable/selector_green.xml +42 -0
- package/android/src/main/res/drawable/selector_purple.xml +42 -0
- package/android/src/main/res/drawable/selector_red.xml +42 -0
- package/android/src/main/res/drawable/selector_yellow.xml +41 -0
- package/android/src/main/res/layout/activity_epub.xml +23 -0
- package/android/src/main/res/layout/activity_main.xml +32 -0
- package/android/src/main/res/layout/activity_reader.xml +6 -0
- package/android/src/main/res/layout/add_catalog_dialog.xml +25 -0
- package/android/src/main/res/layout/filter_row.xml +34 -0
- package/android/src/main/res/layout/filter_window.xml +24 -0
- package/android/src/main/res/layout/fragment_about.xml +150 -0
- package/android/src/main/res/layout/fragment_audiobook.xml +151 -0
- package/android/src/main/res/layout/fragment_bookshelf.xml +35 -0
- package/android/src/main/res/layout/fragment_catalog.xml +56 -0
- package/android/src/main/res/layout/fragment_catalog_feed_list.xml +27 -0
- package/android/src/main/res/layout/fragment_drm_management.xml +284 -0
- package/android/src/main/res/layout/fragment_listview.xml +24 -0
- package/android/src/main/res/layout/fragment_outline.xml +31 -0
- package/android/src/main/res/layout/fragment_publication_detail.xml +55 -0
- package/android/src/main/res/layout/fragment_reader.xml +6 -0
- package/android/src/main/res/layout/fragment_screen_reader.xml +143 -0
- package/android/src/main/res/layout/fragment_search.xml +39 -0
- package/android/src/main/res/layout/item_group_view.xml +22 -0
- package/android/src/main/res/layout/item_recycle_book.xml +55 -0
- package/android/src/main/res/layout/item_recycle_bookmark.xml +72 -0
- package/android/src/main/res/layout/item_recycle_button.xml +23 -0
- package/android/src/main/res/layout/item_recycle_catalog.xml +56 -0
- package/android/src/main/res/layout/item_recycle_highlight.xml +85 -0
- package/android/src/main/res/layout/item_recycle_horizontal.xml +45 -0
- package/android/src/main/res/layout/item_recycle_navigation.xml +34 -0
- package/android/src/main/res/layout/item_recycle_search.xml +14 -0
- package/android/src/main/res/layout/item_spinner_days.xml +19 -0
- package/android/src/main/res/layout/my_fragment.xml +13 -0
- package/android/src/main/res/layout/popup_delete.xml +29 -0
- package/android/src/main/res/layout/popup_note.xml +105 -0
- package/android/src/main/res/layout/popup_passphrase.xml +126 -0
- package/android/src/main/res/layout/popup_window_user_settings.xml +576 -0
- package/android/src/main/res/layout/section_header.xml +25 -0
- package/android/src/main/res/layout/view_action_mode.xml +100 -0
- package/android/src/main/res/layout/view_action_mode_reverse.xml +99 -0
- package/android/src/main/res/menu/bottom_nav_menu.xml +19 -0
- package/android/src/main/res/menu/menu_action_mode.xml +26 -0
- package/android/src/main/res/menu/menu_bookmark.xml +18 -0
- package/android/src/main/res/menu/menu_epub.xml +41 -0
- package/android/src/main/res/menu/menu_filter.xml +21 -0
- package/android/src/main/res/menu/menu_reader.xml +33 -0
- package/android/src/main/res/navigation/navigation.xml +46 -0
- package/android/src/main/res/values/arrays.xml +18 -0
- package/android/src/main/res/values/colors.xml +22 -0
- package/android/src/main/res/values/refs.xml +5 -0
- package/android/src/main/res/values/strings.xml +200 -0
- package/android/src/main/res/values/styles.xml +46 -0
- package/android/src/main/res/xml/network_security_config.xml +38 -0
- package/ios/App/AppModule.swift +62 -0
- package/ios/Common/Paths.swift +52 -0
- package/ios/Common/Publication.swift +15 -0
- package/ios/Common/Toolkit/Extensions/AnyPublisher.swift +14 -0
- package/ios/Common/Toolkit/Extensions/Future.swift +16 -0
- package/ios/Common/Toolkit/Extensions/HTTPClient.swift +65 -0
- package/ios/Common/Toolkit/Extensions/Locator.swift +14 -0
- package/ios/Common/Toolkit/Extensions/String.swift +16 -0
- package/ios/Common/Toolkit/Extensions/UIImage.swift +12 -0
- package/ios/Common/Toolkit/Extensions/UIViewController.swift +19 -0
- package/ios/Common/Toolkit/ScreenOrientation.swift +13 -0
- package/ios/Data/Bookmark.swift +23 -0
- package/ios/Reader/Common/ReaderViewController.swift +309 -0
- package/ios/Reader/EPUB/AssociatedColors.swift +27 -0
- package/ios/Reader/EPUB/EPUBModule.swift +38 -0
- package/ios/Reader/EPUB/EPUBViewController.swift +79 -0
- package/ios/Reader/ReaderError.swift +25 -0
- package/ios/Reader/ReaderFormatModule.swift +27 -0
- package/ios/Reader/ReaderModule.swift +84 -0
- package/ios/Reader/ReaderService.swift +126 -0
- package/ios/Readium-Bridging-Header.h +2 -0
- package/ios/Readium.xcodeproj/project.pbxproj +293 -0
- package/ios/ReadiumView.swift +156 -0
- package/ios/ReadiumViewManager.m +10 -0
- package/ios/ReadiumViewManager.swift +9 -0
- package/lib/commonjs/enums/Appearance.js +16 -0
- package/lib/commonjs/enums/Appearance.js.map +1 -0
- package/lib/commonjs/enums/ColumnCount.js +16 -0
- package/lib/commonjs/enums/ColumnCount.js.map +1 -0
- package/lib/commonjs/enums/FontFamily.js +21 -0
- package/lib/commonjs/enums/FontFamily.js.map +1 -0
- package/lib/commonjs/enums/TextAlignment.js +15 -0
- package/lib/commonjs/enums/TextAlignment.js.map +1 -0
- package/lib/commonjs/enums/index.js +58 -0
- package/lib/commonjs/enums/index.js.map +1 -0
- package/lib/commonjs/index.js +105 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/interfaces/Dimensions.js +2 -0
- package/lib/commonjs/interfaces/Dimensions.js.map +1 -0
- package/lib/commonjs/interfaces/File.js +6 -0
- package/lib/commonjs/interfaces/File.js.map +1 -0
- package/lib/commonjs/interfaces/Locator.js +2 -0
- package/lib/commonjs/interfaces/Locator.js.map +1 -0
- package/lib/commonjs/interfaces/Settings.js +71 -0
- package/lib/commonjs/interfaces/Settings.js.map +1 -0
- package/lib/commonjs/interfaces/index.js +58 -0
- package/lib/commonjs/interfaces/index.js.map +1 -0
- package/lib/commonjs/utils/index.js +30 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/module/enums/Appearance.js +9 -0
- package/lib/module/enums/Appearance.js.map +1 -0
- package/lib/module/enums/ColumnCount.js +9 -0
- package/lib/module/enums/ColumnCount.js.map +1 -0
- package/lib/module/enums/FontFamily.js +14 -0
- package/lib/module/enums/FontFamily.js.map +1 -0
- package/lib/module/enums/TextAlignment.js +8 -0
- package/lib/module/enums/TextAlignment.js.map +1 -0
- package/lib/module/enums/index.js +5 -0
- package/lib/module/enums/index.js.map +1 -0
- package/lib/module/index.js +61 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/interfaces/Dimensions.js +2 -0
- package/lib/module/interfaces/Dimensions.js.map +1 -0
- package/lib/module/interfaces/File.js +2 -0
- package/lib/module/interfaces/File.js.map +1 -0
- package/lib/module/interfaces/Locator.js +2 -0
- package/lib/module/interfaces/Locator.js.map +1 -0
- package/lib/module/interfaces/Settings.js +61 -0
- package/lib/module/interfaces/Settings.js.map +1 -0
- package/lib/module/interfaces/index.js +5 -0
- package/lib/module/interfaces/index.js.map +1 -0
- package/lib/module/utils/index.js +17 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/typescript/enums/Appearance.d.ts +11 -0
- package/lib/typescript/enums/ColumnCount.d.ts +5 -0
- package/lib/typescript/enums/FontFamily.d.ts +10 -0
- package/lib/typescript/enums/TextAlignment.d.ts +4 -0
- package/lib/typescript/enums/index.d.ts +4 -0
- package/lib/typescript/index.d.ts +17 -0
- package/lib/typescript/interfaces/Dimensions.d.ts +4 -0
- package/lib/typescript/interfaces/File.d.ts +11 -0
- package/lib/typescript/interfaces/Locator.d.ts +14 -0
- package/lib/typescript/interfaces/Settings.d.ts +40 -0
- package/lib/typescript/interfaces/index.d.ts +4 -0
- package/lib/typescript/utils/index.d.ts +10 -0
- package/package.json +160 -0
- package/react-native-readium.podspec +25 -0
- package/src/enums/Appearance.ts +14 -0
- package/src/enums/ColumnCount.ts +6 -0
- package/src/enums/FontFamily.ts +11 -0
- package/src/enums/TextAlignment.ts +5 -0
- package/src/enums/index.ts +4 -0
- package/src/index.tsx +78 -0
- package/src/interfaces/Dimensions.ts +4 -0
- package/src/interfaces/File.ts +14 -0
- package/src/interfaces/Locator.ts +14 -0
- package/src/interfaces/Settings.ts +85 -0
- package/src/interfaces/index.ts +4 -0
- package/src/utils/index.ts +18 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
package com.reactnativereadium.epub
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.content.SharedPreferences
|
|
5
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
6
|
+
import org.json.JSONArray
|
|
7
|
+
import org.readium.r2.navigator.R2BasicWebView
|
|
8
|
+
import org.readium.r2.navigator.R2WebView
|
|
9
|
+
import org.readium.r2.navigator.epub.fxl.R2FXLLayout
|
|
10
|
+
import org.readium.r2.navigator.pager.R2ViewPager
|
|
11
|
+
import org.readium.r2.shared.*
|
|
12
|
+
import com.reactnativereadium.R
|
|
13
|
+
import java.io.File
|
|
14
|
+
|
|
15
|
+
class UserSettings(
|
|
16
|
+
var preferences: SharedPreferences,
|
|
17
|
+
val context: Context,
|
|
18
|
+
private val UIPreset: MutableMap<ReadiumCSSName, Boolean>
|
|
19
|
+
) {
|
|
20
|
+
|
|
21
|
+
lateinit var resourcePager: R2ViewPager
|
|
22
|
+
|
|
23
|
+
private val appearanceValues = listOf("readium-default-on", "readium-sepia-on", "readium-night-on")
|
|
24
|
+
private val fontFamilyValues = listOf("Original", "PT Serif", "Roboto", "Source Sans Pro", "Vollkorn", "OpenDyslexic", "AccessibleDfA", "IA Writer Duospace")
|
|
25
|
+
private val textAlignmentValues = listOf("justify", "start")
|
|
26
|
+
private val columnCountValues = listOf("auto", "1", "2")
|
|
27
|
+
|
|
28
|
+
private var fontSize = 100f
|
|
29
|
+
private var fontOverride = false
|
|
30
|
+
private var fontFamily = 0
|
|
31
|
+
private var appearance = 0
|
|
32
|
+
private var verticalScroll = false
|
|
33
|
+
|
|
34
|
+
//Advanced settings
|
|
35
|
+
private var publisherDefaults = false
|
|
36
|
+
private var textAlignment = 0
|
|
37
|
+
private var columnCount = 0
|
|
38
|
+
private var wordSpacing = 0f
|
|
39
|
+
private var letterSpacing = 0f
|
|
40
|
+
private var pageMargins = 2f
|
|
41
|
+
private var lineHeight = 1f
|
|
42
|
+
|
|
43
|
+
private var userProperties: UserProperties
|
|
44
|
+
|
|
45
|
+
init {
|
|
46
|
+
appearance = preferences.getInt(APPEARANCE_REF, appearance)
|
|
47
|
+
verticalScroll = preferences.getBoolean(SCROLL_REF, verticalScroll)
|
|
48
|
+
fontFamily = preferences.getInt(FONT_FAMILY_REF, fontFamily)
|
|
49
|
+
if (fontFamily != 0) {
|
|
50
|
+
fontOverride = true
|
|
51
|
+
}
|
|
52
|
+
publisherDefaults = preferences.getBoolean(PUBLISHER_DEFAULT_REF, publisherDefaults)
|
|
53
|
+
textAlignment = preferences.getInt(TEXT_ALIGNMENT_REF, textAlignment)
|
|
54
|
+
columnCount = preferences.getInt(COLUMN_COUNT_REF, columnCount)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
fontSize = preferences.getFloat(FONT_SIZE_REF, fontSize)
|
|
58
|
+
wordSpacing = preferences.getFloat(WORD_SPACING_REF, wordSpacing)
|
|
59
|
+
letterSpacing = preferences.getFloat(LETTER_SPACING_REF, letterSpacing)
|
|
60
|
+
pageMargins = preferences.getFloat(PAGE_MARGINS_REF, pageMargins)
|
|
61
|
+
lineHeight = preferences.getFloat(LINE_HEIGHT_REF, lineHeight)
|
|
62
|
+
userProperties = getUserSettings()
|
|
63
|
+
|
|
64
|
+
//Setting up screen brightness
|
|
65
|
+
val backLightValue = preferences.getInt("reader_brightness", 50).toFloat() / 100
|
|
66
|
+
val layoutParams = (context as AppCompatActivity).window.attributes
|
|
67
|
+
layoutParams.screenBrightness = backLightValue
|
|
68
|
+
context.window.attributes = layoutParams
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fun updateSettingsFromMap(map: Map<String, Any>) {
|
|
72
|
+
userProperties.properties.forEach { property ->
|
|
73
|
+
val key = property.ref
|
|
74
|
+
val value = map[key]
|
|
75
|
+
|
|
76
|
+
val isPropertyModified = when (property) {
|
|
77
|
+
is Enumerable -> updateEnumerableFromKeyValue(property, key, value)
|
|
78
|
+
is Incremental -> updateIncrementalFromKeyValue(property, key, value)
|
|
79
|
+
is Switchable -> updateSwitchableFromKeyValue(property, key, value)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// apply the changes to the view
|
|
83
|
+
if (isPropertyModified) {
|
|
84
|
+
updateViewCSS(key)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private fun updateEnumerableFromKeyValue(property: Enumerable, key: String, value: Any?): Boolean {
|
|
90
|
+
if (value == null) return false
|
|
91
|
+
var update: Int?
|
|
92
|
+
|
|
93
|
+
if (value is Int) {
|
|
94
|
+
update = value
|
|
95
|
+
} else if (value is Float) {
|
|
96
|
+
update = value.toInt()
|
|
97
|
+
} else if (value is Double) {
|
|
98
|
+
update = value.toInt()
|
|
99
|
+
} else {
|
|
100
|
+
throw Error("Invalid value type '${value.javaClass.simpleName}' passed for setting: $key = $value")
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
property.index = update
|
|
104
|
+
updateEnumerable(property)
|
|
105
|
+
return true
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private fun updateIncrementalFromKeyValue(property: Incremental, key: String, value: Any?): Boolean {
|
|
109
|
+
if (value == null) return false
|
|
110
|
+
var update: Float?
|
|
111
|
+
|
|
112
|
+
if (value is Int) {
|
|
113
|
+
update = value.toFloat()
|
|
114
|
+
} else if (value is Float) {
|
|
115
|
+
update = value
|
|
116
|
+
} else if (value is Double) {
|
|
117
|
+
update = value.toFloat()
|
|
118
|
+
} else {
|
|
119
|
+
throw Error("Invalid value type '${value.javaClass.simpleName}' passed for setting: $key = $value")
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
property.value = update
|
|
123
|
+
updateIncremental(property)
|
|
124
|
+
return true
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private fun updateSwitchableFromKeyValue(property: Switchable, key: String, value: Any?): Boolean {
|
|
128
|
+
if (value == null) return false
|
|
129
|
+
var update: Boolean?
|
|
130
|
+
|
|
131
|
+
if (value is Boolean) {
|
|
132
|
+
update = value
|
|
133
|
+
} else {
|
|
134
|
+
throw Error("Invalid value type '${value.javaClass.simpleName}' passed for setting: $key = $value")
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
property.on = update
|
|
138
|
+
updateSwitchable(property)
|
|
139
|
+
return true
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private fun getUserSettings(): UserProperties {
|
|
143
|
+
|
|
144
|
+
val userProperties = UserProperties()
|
|
145
|
+
// Publisher default system
|
|
146
|
+
userProperties.addSwitchable("readium-advanced-off", "readium-advanced-on", publisherDefaults, PUBLISHER_DEFAULT_REF, PUBLISHER_DEFAULT_NAME)
|
|
147
|
+
// Font override
|
|
148
|
+
userProperties.addSwitchable("readium-font-on", "readium-font-off", fontOverride, FONT_OVERRIDE_REF, FONT_OVERRIDE_NAME)
|
|
149
|
+
// Column count
|
|
150
|
+
userProperties.addEnumerable(columnCount, columnCountValues, COLUMN_COUNT_REF, COLUMN_COUNT_NAME)
|
|
151
|
+
// Appearance
|
|
152
|
+
userProperties.addEnumerable(appearance, appearanceValues, APPEARANCE_REF, APPEARANCE_NAME)
|
|
153
|
+
// Page margins
|
|
154
|
+
userProperties.addIncremental(pageMargins, 0.5f, 4f, 0.25f, "", PAGE_MARGINS_REF, PAGE_MARGINS_NAME)
|
|
155
|
+
// Text alignment
|
|
156
|
+
userProperties.addEnumerable(textAlignment, textAlignmentValues, TEXT_ALIGNMENT_REF, TEXT_ALIGNMENT_NAME)
|
|
157
|
+
// Font family
|
|
158
|
+
userProperties.addEnumerable(fontFamily, fontFamilyValues, FONT_FAMILY_REF, FONT_FAMILY_NAME)
|
|
159
|
+
// Font size
|
|
160
|
+
userProperties.addIncremental(fontSize, 100f, 300f, 25f, "%", FONT_SIZE_REF, FONT_SIZE_NAME)
|
|
161
|
+
// Line height
|
|
162
|
+
userProperties.addIncremental(lineHeight, 1f, 2f, 0.25f, "", LINE_HEIGHT_REF, LINE_HEIGHT_NAME)
|
|
163
|
+
// Word spacing
|
|
164
|
+
userProperties.addIncremental(wordSpacing, 0f, 0.5f, 0.25f, "rem", WORD_SPACING_REF, WORD_SPACING_NAME)
|
|
165
|
+
// Letter spacing
|
|
166
|
+
userProperties.addIncremental(letterSpacing, 0f, 0.5f, 0.0625f, "em", LETTER_SPACING_REF, LETTER_SPACING_NAME)
|
|
167
|
+
// Scroll
|
|
168
|
+
userProperties.addSwitchable("readium-scroll-on", "readium-scroll-off", verticalScroll, SCROLL_REF, SCROLL_NAME)
|
|
169
|
+
|
|
170
|
+
return userProperties
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private fun makeJson(): JSONArray {
|
|
174
|
+
val array = JSONArray()
|
|
175
|
+
for (userProperty in userProperties.properties) {
|
|
176
|
+
array.put(userProperty.getJson())
|
|
177
|
+
}
|
|
178
|
+
return array
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
fun saveChanges() {
|
|
183
|
+
val json = makeJson()
|
|
184
|
+
val dir = File(context.filesDir.path + "/" + Injectable.Style.rawValue + "/")
|
|
185
|
+
dir.mkdirs()
|
|
186
|
+
val file = File(dir, "UserProperties.json")
|
|
187
|
+
file.printWriter().use { out ->
|
|
188
|
+
out.println(json)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private fun updateEnumerable(enumerable: Enumerable) {
|
|
193
|
+
preferences.edit().putInt(enumerable.ref, enumerable.index).apply()
|
|
194
|
+
saveChanges()
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
private fun updateSwitchable(switchable: Switchable) {
|
|
199
|
+
preferences.edit().putBoolean(switchable.ref, switchable.on).apply()
|
|
200
|
+
saveChanges()
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private fun updateIncremental(incremental: Incremental) {
|
|
204
|
+
preferences.edit().putFloat(incremental.ref, incremental.value).apply()
|
|
205
|
+
saveChanges()
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
fun updateViewCSS(ref: String) {
|
|
209
|
+
for (i in 0 until resourcePager.childCount) {
|
|
210
|
+
val webView = resourcePager.getChildAt(i).findViewById(R.id.webView) as? R2WebView
|
|
211
|
+
webView?.let {
|
|
212
|
+
applyCSS(webView, ref)
|
|
213
|
+
} ?: run {
|
|
214
|
+
val zoomView = resourcePager.getChildAt(i).findViewById(R.id.r2FXLLayout) as R2FXLLayout
|
|
215
|
+
val webView1 = zoomView.findViewById(R.id.firstWebView) as? R2BasicWebView
|
|
216
|
+
val webView2 = zoomView.findViewById(R.id.secondWebView) as? R2BasicWebView
|
|
217
|
+
val webViewSingle = zoomView.findViewById(R.id.webViewSingle) as? R2BasicWebView
|
|
218
|
+
|
|
219
|
+
webView1?.let {
|
|
220
|
+
applyCSS(webView1, ref)
|
|
221
|
+
}
|
|
222
|
+
webView2?.let {
|
|
223
|
+
applyCSS(webView2, ref)
|
|
224
|
+
}
|
|
225
|
+
webViewSingle?.let {
|
|
226
|
+
applyCSS(webViewSingle, ref)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private fun applyCSS(view: R2BasicWebView, ref: String) {
|
|
233
|
+
val userSetting = userProperties.getByRef<UserProperty>(ref)
|
|
234
|
+
view.setProperty(userSetting.name, userSetting.toString())
|
|
235
|
+
}
|
|
236
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
package com.reactnativereadium.reader
|
|
2
|
+
|
|
3
|
+
import android.os.Bundle
|
|
4
|
+
import android.view.*
|
|
5
|
+
import androidx.fragment.app.Fragment
|
|
6
|
+
import androidx.lifecycle.lifecycleScope
|
|
7
|
+
import kotlinx.coroutines.flow.launchIn
|
|
8
|
+
import kotlinx.coroutines.flow.onEach
|
|
9
|
+
import org.readium.r2.navigator.*
|
|
10
|
+
import org.readium.r2.shared.publication.Locator
|
|
11
|
+
import com.reactnativereadium.R
|
|
12
|
+
import com.reactnativereadium.utils.EventChannel
|
|
13
|
+
import kotlinx.coroutines.channels.Channel
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Base reader fragment class
|
|
17
|
+
*
|
|
18
|
+
* Provides common menu items and saves last location on stop.
|
|
19
|
+
*/
|
|
20
|
+
@OptIn(ExperimentalDecorator::class)
|
|
21
|
+
abstract class BaseReaderFragment : Fragment() {
|
|
22
|
+
val channel = EventChannel(
|
|
23
|
+
Channel<ReaderViewModel.Event>(Channel.BUFFERED),
|
|
24
|
+
lifecycleScope
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
protected abstract val model: ReaderViewModel
|
|
28
|
+
protected abstract val navigator: Navigator
|
|
29
|
+
|
|
30
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
31
|
+
setHasOptionsMenu(true)
|
|
32
|
+
super.onCreate(savedInstanceState)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
36
|
+
super.onViewCreated(view, savedInstanceState)
|
|
37
|
+
|
|
38
|
+
val viewScope = viewLifecycleOwner.lifecycleScope
|
|
39
|
+
|
|
40
|
+
navigator.currentLocator
|
|
41
|
+
.onEach { channel.send(ReaderViewModel.Event.LocatorUpdate(it)) }
|
|
42
|
+
.launchIn(viewScope)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun onHiddenChanged(hidden: Boolean) {
|
|
46
|
+
super.onHiddenChanged(hidden)
|
|
47
|
+
setMenuVisibility(!hidden)
|
|
48
|
+
requireActivity().invalidateOptionsMenu()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// TODO: this should probably be removed
|
|
52
|
+
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
|
|
53
|
+
menuInflater.inflate(R.menu.menu_reader, menu)
|
|
54
|
+
menu.findItem(R.id.drm).isVisible = false
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
58
|
+
return when (item.itemId) {
|
|
59
|
+
R.id.toc -> {
|
|
60
|
+
model.channel.send(ReaderViewModel.Event.OpenOutlineRequested)
|
|
61
|
+
true
|
|
62
|
+
}
|
|
63
|
+
R.id.drm -> {
|
|
64
|
+
model.channel.send(ReaderViewModel.Event.OpenDrmManagementRequested)
|
|
65
|
+
true
|
|
66
|
+
}
|
|
67
|
+
else -> false
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fun go(locator: Locator, animated: Boolean): Boolean {
|
|
72
|
+
// don't attempt to navigate if we're already there
|
|
73
|
+
val currentLocator = navigator.currentLocator.value
|
|
74
|
+
if (locator.hashCode() == currentLocator.hashCode()) {
|
|
75
|
+
return true
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return navigator.go(locator, animated)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2021 Readium Foundation. All rights reserved.
|
|
3
|
+
* Use of this source code is governed by the BSD-style license
|
|
4
|
+
* available in the top-level LICENSE file of the project.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
package com.reactnativereadium.reader
|
|
8
|
+
|
|
9
|
+
import android.graphics.Color
|
|
10
|
+
import android.graphics.PointF
|
|
11
|
+
import android.os.Bundle
|
|
12
|
+
import android.view.*
|
|
13
|
+
import android.view.accessibility.AccessibilityManager
|
|
14
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
15
|
+
import androidx.appcompat.widget.SearchView
|
|
16
|
+
import androidx.fragment.app.commitNow
|
|
17
|
+
import androidx.lifecycle.lifecycleScope
|
|
18
|
+
import androidx.lifecycle.ViewModelProvider
|
|
19
|
+
import com.reactnativereadium.epub.UserSettings
|
|
20
|
+
import com.reactnativereadium.R
|
|
21
|
+
import com.reactnativereadium.utils.toggleSystemUi
|
|
22
|
+
import java.net.URL
|
|
23
|
+
import kotlinx.coroutines.delay
|
|
24
|
+
import org.readium.r2.navigator.epub.EpubNavigatorFragment
|
|
25
|
+
import org.readium.r2.navigator.ExperimentalDecorator
|
|
26
|
+
import org.readium.r2.navigator.Navigator
|
|
27
|
+
import org.readium.r2.shared.APPEARANCE_REF
|
|
28
|
+
import org.readium.r2.shared.publication.Locator
|
|
29
|
+
import org.readium.r2.shared.publication.Publication
|
|
30
|
+
import org.readium.r2.shared.ReadiumCSSName
|
|
31
|
+
import org.readium.r2.shared.SCROLL_REF
|
|
32
|
+
|
|
33
|
+
@OptIn(ExperimentalDecorator::class)
|
|
34
|
+
class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listener {
|
|
35
|
+
|
|
36
|
+
override lateinit var model: ReaderViewModel
|
|
37
|
+
override lateinit var navigator: Navigator
|
|
38
|
+
private lateinit var publication: Publication
|
|
39
|
+
lateinit var navigatorFragment: EpubNavigatorFragment
|
|
40
|
+
private lateinit var factory: ReaderViewModel.Factory
|
|
41
|
+
|
|
42
|
+
private lateinit var menuScreenReader: MenuItem
|
|
43
|
+
private lateinit var menuSearch: MenuItem
|
|
44
|
+
lateinit var menuSearchView: SearchView
|
|
45
|
+
|
|
46
|
+
private lateinit var userSettings: UserSettings
|
|
47
|
+
private var isScreenReaderVisible = false
|
|
48
|
+
private var isSearchViewIconified = true
|
|
49
|
+
|
|
50
|
+
// Accessibility
|
|
51
|
+
private var isExploreByTouchEnabled = false
|
|
52
|
+
|
|
53
|
+
fun initFactory(
|
|
54
|
+
publication: Publication,
|
|
55
|
+
initialLocation: Locator?
|
|
56
|
+
) {
|
|
57
|
+
factory = ReaderViewModel.Factory(
|
|
58
|
+
publication,
|
|
59
|
+
initialLocation
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fun updateSettingsFromMap(map: Map<String, Any>) {
|
|
64
|
+
if (userSettings != null) {
|
|
65
|
+
userSettings.updateSettingsFromMap(map)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
70
|
+
// FIXME: this should be checked
|
|
71
|
+
// check(R2App.isServerStarted)
|
|
72
|
+
|
|
73
|
+
if (savedInstanceState != null) {
|
|
74
|
+
isScreenReaderVisible = savedInstanceState.getBoolean(IS_SCREEN_READER_VISIBLE_KEY)
|
|
75
|
+
isSearchViewIconified = savedInstanceState.getBoolean(IS_SEARCH_VIEW_ICONIFIED)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ViewModelProvider(this, factory)
|
|
79
|
+
.get(ReaderViewModel::class.java)
|
|
80
|
+
.let {
|
|
81
|
+
model = it
|
|
82
|
+
publication = it.publication
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
val baseUrl = checkNotNull(requireArguments().getString(BASE_URL_ARG))
|
|
86
|
+
|
|
87
|
+
childFragmentManager.fragmentFactory =
|
|
88
|
+
EpubNavigatorFragment.createFactory(
|
|
89
|
+
publication = publication,
|
|
90
|
+
baseUrl = baseUrl,
|
|
91
|
+
initialLocator = model.initialLocation,
|
|
92
|
+
listener = this,
|
|
93
|
+
config = EpubNavigatorFragment.Configuration().apply {
|
|
94
|
+
// Register the HTML template for our custom [DecorationStyleAnnotationMark].
|
|
95
|
+
// TODO: remove?
|
|
96
|
+
/* decorationTemplates[DecorationStyleAnnotationMark::class] = annotationMarkTemplate(activity) */
|
|
97
|
+
/* selectionActionModeCallback = customSelectionActionModeCallback */
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
// TODO: add search back in
|
|
101
|
+
// childFragmentManager.setFragmentResultListener(
|
|
102
|
+
// SearchFragment::class.java.name,
|
|
103
|
+
// this,
|
|
104
|
+
// FragmentResultListener { _, result ->
|
|
105
|
+
// menuSearch.collapseActionView()
|
|
106
|
+
// result.getParcelable<Locator>(SearchFragment::class.java.name)?.let {
|
|
107
|
+
// navigatorFragment.go(it)
|
|
108
|
+
// }
|
|
109
|
+
// }
|
|
110
|
+
// )
|
|
111
|
+
// TODO: add TTS back in
|
|
112
|
+
// childFragmentManager.setFragmentResultListener(
|
|
113
|
+
// ScreenReaderContract.REQUEST_KEY,
|
|
114
|
+
// this,
|
|
115
|
+
// FragmentResultListener { _, result ->
|
|
116
|
+
// val locator = ScreenReaderContract.parseResult(result).locator
|
|
117
|
+
// if (locator.href != navigator.currentLocator.value.href) {
|
|
118
|
+
// navigator.go(locator)
|
|
119
|
+
// }
|
|
120
|
+
// }
|
|
121
|
+
// )
|
|
122
|
+
|
|
123
|
+
setHasOptionsMenu(true)
|
|
124
|
+
|
|
125
|
+
super.onCreate(savedInstanceState)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
|
129
|
+
val view = super.onCreateView(inflater, container, savedInstanceState)
|
|
130
|
+
val navigatorFragmentTag = getString(R.string.epub_navigator_tag)
|
|
131
|
+
|
|
132
|
+
if (savedInstanceState == null) {
|
|
133
|
+
childFragmentManager.commitNow {
|
|
134
|
+
add(R.id.fragment_reader_container, EpubNavigatorFragment::class.java, Bundle(), navigatorFragmentTag)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
navigator = childFragmentManager.findFragmentByTag(navigatorFragmentTag) as Navigator
|
|
138
|
+
navigatorFragment = navigator as EpubNavigatorFragment
|
|
139
|
+
|
|
140
|
+
return view
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
144
|
+
super.onViewCreated(view, savedInstanceState)
|
|
145
|
+
|
|
146
|
+
val activity = requireActivity()
|
|
147
|
+
userSettings = UserSettings(navigatorFragment.preferences, activity, publication.userSettingsUIPreset)
|
|
148
|
+
|
|
149
|
+
// This is a hack to draw the right background color on top and bottom blank spaces
|
|
150
|
+
navigatorFragment.lifecycleScope.launchWhenStarted {
|
|
151
|
+
val appearancePref = navigatorFragment.preferences.getInt(APPEARANCE_REF, 0)
|
|
152
|
+
val backgroundsColors = mutableListOf("#ffffff", "#faf4e8", "#000000")
|
|
153
|
+
navigatorFragment.resourcePager.setBackgroundColor(Color.parseColor(backgroundsColors[appearancePref]))
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
override fun onResume() {
|
|
158
|
+
super.onResume()
|
|
159
|
+
val activity = requireActivity()
|
|
160
|
+
|
|
161
|
+
userSettings.resourcePager = navigatorFragment.resourcePager
|
|
162
|
+
|
|
163
|
+
// If TalkBack or any touch exploration service is activated we force scroll mode (and
|
|
164
|
+
// override user preferences)
|
|
165
|
+
val am = activity.getSystemService(AppCompatActivity.ACCESSIBILITY_SERVICE) as AccessibilityManager
|
|
166
|
+
isExploreByTouchEnabled = am.isTouchExplorationEnabled
|
|
167
|
+
|
|
168
|
+
if (isExploreByTouchEnabled) {
|
|
169
|
+
// Preset & preferences adapted
|
|
170
|
+
publication.userSettingsUIPreset[ReadiumCSSName.ref(SCROLL_REF)] = true
|
|
171
|
+
navigatorFragment.preferences.edit().putBoolean(SCROLL_REF, true).apply() //overriding user preferences
|
|
172
|
+
userSettings.saveChanges()
|
|
173
|
+
|
|
174
|
+
lifecycleScope.launchWhenResumed {
|
|
175
|
+
delay(500)
|
|
176
|
+
userSettings.updateViewCSS(SCROLL_REF)
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
if (publication.cssStyle != "cjk-vertical") {
|
|
180
|
+
publication.userSettingsUIPreset.remove(ReadiumCSSName.ref(SCROLL_REF))
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
|
|
186
|
+
super.onCreateOptionsMenu(menu, menuInflater)
|
|
187
|
+
menuInflater.inflate(R.menu.menu_epub, menu)
|
|
188
|
+
|
|
189
|
+
menuScreenReader = menu.findItem(R.id.screen_reader)
|
|
190
|
+
menuSearch = menu.findItem(R.id.search)
|
|
191
|
+
menuSearchView = menuSearch.actionView as SearchView
|
|
192
|
+
|
|
193
|
+
/* connectSearch() */
|
|
194
|
+
if (!isSearchViewIconified) menuSearch.expandActionView()
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
override fun onSaveInstanceState(outState: Bundle) {
|
|
198
|
+
super.onSaveInstanceState(outState)
|
|
199
|
+
outState.putBoolean(IS_SCREEN_READER_VISIBLE_KEY, isScreenReaderVisible)
|
|
200
|
+
outState.putBoolean(IS_SEARCH_VIEW_ICONIFIED, isSearchViewIconified)
|
|
201
|
+
}
|
|
202
|
+
// TODO: add search
|
|
203
|
+
// private fun connectSearch() {
|
|
204
|
+
// menuSearch.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
|
|
205
|
+
//
|
|
206
|
+
// override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
|
|
207
|
+
// if (isSearchViewIconified) { // It is not a state restoration.
|
|
208
|
+
// showSearchFragment()
|
|
209
|
+
// }
|
|
210
|
+
//
|
|
211
|
+
// isSearchViewIconified = false
|
|
212
|
+
// return true
|
|
213
|
+
// }
|
|
214
|
+
//
|
|
215
|
+
// override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
|
|
216
|
+
// isSearchViewIconified = true
|
|
217
|
+
// childFragmentManager.popBackStack()
|
|
218
|
+
// menuSearchView.clearFocus()
|
|
219
|
+
//
|
|
220
|
+
// return true
|
|
221
|
+
// }
|
|
222
|
+
// })
|
|
223
|
+
//
|
|
224
|
+
// menuSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
|
225
|
+
//
|
|
226
|
+
// override fun onQueryTextSubmit(query: String): Boolean {
|
|
227
|
+
// model.search(query)
|
|
228
|
+
// menuSearchView.clearFocus()
|
|
229
|
+
//
|
|
230
|
+
// return false
|
|
231
|
+
// }
|
|
232
|
+
//
|
|
233
|
+
// override fun onQueryTextChange(s: String): Boolean {
|
|
234
|
+
// return false
|
|
235
|
+
// }
|
|
236
|
+
// })
|
|
237
|
+
//
|
|
238
|
+
// menuSearchView.findViewById<ImageView>(R.id.search_close_btn).setOnClickListener {
|
|
239
|
+
// menuSearchView.requestFocus()
|
|
240
|
+
// model.cancelSearch()
|
|
241
|
+
// menuSearchView.setQuery("", false)
|
|
242
|
+
//
|
|
243
|
+
// (activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.showSoftInput(
|
|
244
|
+
// this.view, InputMethodManager.SHOW_FORCED
|
|
245
|
+
// )
|
|
246
|
+
// }
|
|
247
|
+
// }
|
|
248
|
+
|
|
249
|
+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
250
|
+
if (super.onOptionsItemSelected(item)) {
|
|
251
|
+
return true
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return when (item.itemId) {
|
|
255
|
+
R.id.settings -> {
|
|
256
|
+
/* TODO: this should be stripped out */
|
|
257
|
+
/* userSettings.userSettingsPopUp().showAsDropDown(requireActivity().findViewById(R.id.settings), 0, 0, Gravity.END) */
|
|
258
|
+
true
|
|
259
|
+
}
|
|
260
|
+
R.id.search -> {
|
|
261
|
+
super.onOptionsItemSelected(item)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
android.R.id.home -> {
|
|
265
|
+
menuSearch.collapseActionView()
|
|
266
|
+
true
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// TODO: tts
|
|
270
|
+
// R.id.screen_reader -> {
|
|
271
|
+
// if (isScreenReaderVisible) {
|
|
272
|
+
// closeScreenReaderFragment()
|
|
273
|
+
// } else {
|
|
274
|
+
// showScreenReaderFragment()
|
|
275
|
+
// }
|
|
276
|
+
// true
|
|
277
|
+
// }
|
|
278
|
+
else -> false
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
override fun onTap(point: PointF): Boolean {
|
|
283
|
+
requireActivity().toggleSystemUi()
|
|
284
|
+
return true
|
|
285
|
+
}
|
|
286
|
+
// TODO: search
|
|
287
|
+
// private fun showSearchFragment() {
|
|
288
|
+
// childFragmentManager.commit {
|
|
289
|
+
// childFragmentManager.findFragmentByTag(SEARCH_FRAGMENT_TAG)?.let { remove(it) }
|
|
290
|
+
// add(R.id.fragment_reader_container, SearchFragment::class.java, Bundle(), SEARCH_FRAGMENT_TAG)
|
|
291
|
+
// hide(navigatorFragment)
|
|
292
|
+
// addToBackStack(SEARCH_FRAGMENT_TAG)
|
|
293
|
+
// }
|
|
294
|
+
// }
|
|
295
|
+
|
|
296
|
+
// TODO: tts
|
|
297
|
+
// private fun showScreenReaderFragment() {
|
|
298
|
+
// menuScreenReader.title = resources.getString(R.string.epubactivity_read_aloud_stop)
|
|
299
|
+
// isScreenReaderVisible = true
|
|
300
|
+
// val arguments = ScreenReaderContract.createArguments(navigator.currentLocator.value)
|
|
301
|
+
// childFragmentManager.commit {
|
|
302
|
+
// add(R.id.fragment_reader_container, ScreenReaderFragment::class.java, arguments)
|
|
303
|
+
// hide(navigatorFragment)
|
|
304
|
+
// addToBackStack(null)
|
|
305
|
+
// }
|
|
306
|
+
// }
|
|
307
|
+
//
|
|
308
|
+
// private fun closeScreenReaderFragment() {
|
|
309
|
+
// menuScreenReader.title = resources.getString(R.string.epubactivity_read_aloud_start)
|
|
310
|
+
// isScreenReaderVisible = false
|
|
311
|
+
// childFragmentManager.popBackStack()
|
|
312
|
+
// }
|
|
313
|
+
|
|
314
|
+
companion object {
|
|
315
|
+
|
|
316
|
+
private const val BASE_URL_ARG = "baseUrl"
|
|
317
|
+
|
|
318
|
+
private const val SEARCH_FRAGMENT_TAG = "search"
|
|
319
|
+
|
|
320
|
+
private const val IS_SCREEN_READER_VISIBLE_KEY = "isScreenReaderVisible"
|
|
321
|
+
|
|
322
|
+
private const val IS_SEARCH_VIEW_ICONIFIED = "isSearchViewIconified"
|
|
323
|
+
|
|
324
|
+
fun newInstance(baseUrl: URL): EpubReaderFragment {
|
|
325
|
+
return EpubReaderFragment().apply {
|
|
326
|
+
arguments = Bundle().apply {
|
|
327
|
+
putString(BASE_URL_ARG, baseUrl.toString())
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/* TODO: remove */
|
|
335
|
+
// /**
|
|
336
|
+
// * Example of an HTML template for a custom Decoration Style.
|
|
337
|
+
// *
|
|
338
|
+
// * This one will display a tinted "pen" icon in the page margin to show that a highlight has an
|
|
339
|
+
// * associated note.
|
|
340
|
+
// */
|
|
341
|
+
// @OptIn(ExperimentalDecorator::class)
|
|
342
|
+
// private fun annotationMarkTemplate(context: Context, @ColorInt defaultTint: Int = Color.YELLOW): HtmlDecorationTemplate {
|
|
343
|
+
// // Converts the pen icon to a base 64 data URL, to be embedded in the decoration stylesheet.
|
|
344
|
+
// // Alternatively, serve the image with the local HTTP server and use its URL.
|
|
345
|
+
// val imageUrl = ContextCompat.getDrawable(context, R.drawable.ic_baseline_edit_24)
|
|
346
|
+
// ?.toBitmap()?.toDataUrl()
|
|
347
|
+
// requireNotNull(imageUrl)
|
|
348
|
+
//
|
|
349
|
+
// val className = "testapp-annotation-mark"
|
|
350
|
+
// return HtmlDecorationTemplate(
|
|
351
|
+
// layout = HtmlDecorationTemplate.Layout.BOUNDS,
|
|
352
|
+
// width = HtmlDecorationTemplate.Width.PAGE,
|
|
353
|
+
// element = { decoration ->
|
|
354
|
+
// val style = decoration.style as? DecorationStyleAnnotationMark
|
|
355
|
+
// val tint = style?.tint ?: defaultTint
|
|
356
|
+
// // Using `data-activable=1` prevents the whole decoration container from being
|
|
357
|
+
// // clickable. Only the icon will respond to activation events.
|
|
358
|
+
// """
|
|
359
|
+
// <div><div data-activable="1" class="$className" style="background-color: ${tint.toCss()} !important"/></div>"
|
|
360
|
+
// """
|
|
361
|
+
// },
|
|
362
|
+
// stylesheet = """
|
|
363
|
+
// .$className {
|
|
364
|
+
// float: left;
|
|
365
|
+
// margin-left: 8px;
|
|
366
|
+
// width: 30px;
|
|
367
|
+
// height: 30px;
|
|
368
|
+
// border-radius: 50%;
|
|
369
|
+
// background: url('$imageUrl') no-repeat center;
|
|
370
|
+
// background-size: auto 50%;
|
|
371
|
+
// opacity: 0.8;
|
|
372
|
+
// }
|
|
373
|
+
// """
|
|
374
|
+
// )
|
|
375
|
+
// }
|