react-native-readium 3.0.3 → 4.0.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.
Files changed (44) hide show
  1. package/README.md +2 -1
  2. package/android/src/main/java/com/reactnativereadium/ReadiumView.kt +9 -10
  3. package/android/src/main/java/com/reactnativereadium/ReadiumViewManager.kt +7 -6
  4. package/android/src/main/java/com/reactnativereadium/reader/EpubReaderFragment.kt +25 -47
  5. package/android/src/main/java/com/reactnativereadium/reader/ReaderService.kt +2 -15
  6. package/android/src/main/java/com/reactnativereadium/utils/FragmentFactory.kt +1 -1
  7. package/ios/App/AppModule.swift +1 -1
  8. package/ios/Common/EPUBPreferences.swift +8 -0
  9. package/ios/Reader/Common/ReaderViewController.swift +8 -14
  10. package/ios/Reader/EPUB/AssociatedColors.swift +7 -7
  11. package/ios/Reader/EPUB/EPUBModule.swift +6 -7
  12. package/ios/Reader/EPUB/EPUBViewController.swift +8 -10
  13. package/ios/Reader/ReaderFormatModule.swift +3 -4
  14. package/ios/Reader/ReaderModule.swift +3 -7
  15. package/ios/Reader/ReaderService.swift +4 -19
  16. package/ios/ReadiumView.swift +31 -33
  17. package/ios/ReadiumViewManager.m +1 -1
  18. package/lib/src/components/ReadiumView.d.ts +4 -2
  19. package/lib/src/components/ReadiumView.js +4 -4
  20. package/lib/src/components/ReadiumView.web.d.ts +5 -1
  21. package/lib/src/components/ReadiumView.web.js +2 -2
  22. package/lib/src/interfaces/BaseReadiumViewProps.d.ts +1 -2
  23. package/lib/src/interfaces/Preferences.d.ts +27 -0
  24. package/lib/src/interfaces/Preferences.js +1 -0
  25. package/lib/src/interfaces/index.d.ts +1 -1
  26. package/lib/src/interfaces/index.js +1 -1
  27. package/lib/src/utils/RANGES.js +1 -1
  28. package/lib/web/hooks/useReaderRef.js +3 -3
  29. package/lib/web/hooks/useSettingsObserver.d.ts +2 -2
  30. package/lib/web/hooks/useSettingsObserver.js +39 -5
  31. package/package.json +1 -1
  32. package/react-native-readium.podspec +2 -0
  33. package/src/components/ReadiumView.tsx +16 -7
  34. package/src/components/ReadiumView.web.tsx +7 -3
  35. package/src/interfaces/BaseReadiumViewProps.ts +1 -3
  36. package/src/interfaces/Preferences.ts +35 -0
  37. package/src/interfaces/index.ts +1 -1
  38. package/src/utils/RANGES.ts +1 -1
  39. package/web/hooks/useReaderRef.ts +3 -3
  40. package/web/hooks/useSettingsObserver.ts +52 -7
  41. package/android/src/main/java/com/reactnativereadium/epub/UserSettings.kt +0 -246
  42. package/lib/src/interfaces/Settings.d.ts +0 -40
  43. package/lib/src/interfaces/Settings.js +0 -61
  44. package/src/interfaces/Settings.ts +0 -75
package/README.md CHANGED
@@ -85,6 +85,7 @@ target 'ExampleApp' do
85
85
  config = use_native_modules!
86
86
  ...
87
87
  pod 'GCDWebServer', podspec: 'https://raw.githubusercontent.com/readium/GCDWebServer/3.7.5/GCDWebServer.podspec', modular_headers: true
88
+ pod 'ReadiumAdapterGCDWebServer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.6.0/Support/CocoaPods/ReadiumAdapterGCDWebServer.podspec', modular_headers: true
88
89
  pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.6.0/Support/CocoaPods/ReadiumNavigator.podspec'
89
90
  pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.6.0/Support/CocoaPods/ReadiumShared.podspec'
90
91
  pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.6.0/Support/CocoaPods/ReadiumStreamer.podspec'
@@ -160,7 +161,7 @@ DRM is not supported at this time. However, there is a clear path to [support it
160
161
  |------|------|----------|-------------|
161
162
  | `file` | [`File`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/File.ts) | :x: | A file object containing the path to the eBook file on disk. |
162
163
  | `location` | [`Locator`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/Locator.ts) \| [`Link`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/Link.ts) | :white_check_mark: | A locator prop that allows you to externally control the location of the reader (e.g. Chapters or Bookmarks). <br/><br/>:warning: If you want to set the `location` of an ebook on initial load, you should use the `File.initialLocation` property (look at the `file` prop). See more [here](https://github.com/5-stones/react-native-readium/issues/16#issuecomment-1344128937) |
163
- | `settings` | [`Partial<Settings>`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/Settings.ts) | :white_check_mark: | An object that allows you to control various aspects of the reader's UI (epub only) |
164
+ | `preferences` | [`Partial<Preferences>`](https://github.com/readium/swift-toolkit/blob/main/docs/Guides/Navigator%20Preferences.md#appendix-preference-constraints) | :white_check_mark: | An object that allows you to control various aspects of the reader's UI (epub only) |
164
165
  | `style` | `ViewStyle` | :white_check_mark: | A traditional style object. |
165
166
  | `onLocationChange` | `(locator: Locator) => void` | :white_check_mark: | A callback that fires whenever the location is changed (e.g. the user transitions to a new page)|
166
167
  | `onTableOfContents` | `(toc: Link[] \| null) => void` | :white_check_mark: | A callback that fires once the file is parsed and emits the table of contents embedded in the file. Returns `null` or an empty `[]` if no TOC exists. See the [`Link`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/Link.ts) interface for more info. |
@@ -9,9 +9,12 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
9
9
  import com.reactnativereadium.reader.BaseReaderFragment
10
10
  import com.reactnativereadium.reader.EpubReaderFragment
11
11
  import com.reactnativereadium.reader.ReaderViewModel
12
+ import com.reactnativereadium.reader.VisualReaderFragment
12
13
  import com.reactnativereadium.utils.Dimensions
13
14
  import com.reactnativereadium.utils.File
14
15
  import com.reactnativereadium.utils.LinkOrLocator
16
+ import org.readium.r2.navigator.epub.EpubNavigatorFragment
17
+ import org.readium.r2.navigator.epub.EpubPreferences
15
18
  import org.readium.r2.shared.extensions.toMap
16
19
 
17
20
  class ReadiumView(
@@ -21,7 +24,7 @@ class ReadiumView(
21
24
  var file: File? = null
22
25
  var fragment: BaseReaderFragment? = null
23
26
  var isViewInitialized: Boolean = false
24
- var lateInitSettings: Map<String, Any>? = null
27
+ var lateInitSerializedUserPreferences: String? = null
25
28
 
26
29
  fun updateLocation(location: LinkOrLocator) : Boolean {
27
30
  if (fragment == null) {
@@ -31,25 +34,21 @@ class ReadiumView(
31
34
  }
32
35
  }
33
36
 
34
- fun updateSettingsFromMap(map: Map<String, Any>?) {
35
- if (map == null) {
36
- return
37
- } else if (fragment == null) {
38
- lateInitSettings = map
37
+ fun updatePreferencesFromJsonString(preferences: String?) {
38
+ lateInitSerializedUserPreferences = preferences
39
+ if (preferences == null || fragment == null) {
39
40
  return
40
41
  }
41
42
 
42
43
  if (fragment is EpubReaderFragment) {
43
- (fragment as EpubReaderFragment).updateSettingsFromMap(map)
44
+ (fragment as EpubReaderFragment).updatePreferencesFromJsonString(preferences)
44
45
  }
45
-
46
- lateInitSettings = null
47
46
  }
48
47
 
49
48
  fun addFragment(frag: BaseReaderFragment) {
50
49
  fragment = frag
51
50
  setupLayout()
52
- updateSettingsFromMap(lateInitSettings)
51
+ lateInitSerializedUserPreferences?.let { updatePreferencesFromJsonString(it)}
53
52
  val activity: FragmentActivity? = reactContext.currentActivity as FragmentActivity?
54
53
  activity!!.supportFragmentManager
55
54
  .beginTransaction()
@@ -84,11 +84,14 @@ class ReadiumViewManager(
84
84
  fun locationToLinkOrLocator(location: ReadableMap): LinkOrLocator? {
85
85
  val json = JSONObject(location.toHashMap() as HashMap<*, *>)
86
86
  val hasLocations = json.has("locations")
87
+ val hasType = json.has("type") && !json.getString("type").isEmpty()
87
88
  val hasChildren = json.has("children")
88
89
  val hasHashHref = (json.get("href") as String).contains("#")
90
+ val hasTemplated = json.has("templated")
91
+
89
92
  var linkOrLocator: LinkOrLocator? = null
90
93
 
91
- if ((hasChildren || hasHashHref) && !hasLocations) {
94
+ if ((!hasType || hasChildren || hasHashHref || hasTemplated) && !hasLocations) {
92
95
  val link = Link.fromJSON(json)
93
96
  if (link != null) {
94
97
  linkOrLocator = LinkOrLocator.Link(link)
@@ -112,11 +115,9 @@ class ReadiumViewManager(
112
115
  }
113
116
  }
114
117
 
115
- @ReactProp(name = "settings")
116
- fun setSettings(view: ReadiumView, settings: ReadableMap) {
117
- val map = mutableMapOf<String, Any>()
118
- settings.toHashMap().forEach { (key, value) -> if (value != null) map[key] = value }
119
- view.updateSettingsFromMap(map)
118
+ @ReactProp(name = "preferences")
119
+ fun setPreferences(view: ReadiumView, serialisedPreferences: String) {
120
+ view.updatePreferencesFromJsonString(serialisedPreferences)
120
121
  }
121
122
 
122
123
  @ReactPropGroup(names = ["width", "height"], customType = "Style")
@@ -14,9 +14,7 @@ import android.view.accessibility.AccessibilityManager
14
14
  import androidx.appcompat.app.AppCompatActivity
15
15
  import androidx.appcompat.widget.SearchView
16
16
  import androidx.fragment.app.commitNow
17
- import androidx.lifecycle.lifecycleScope
18
17
  import androidx.lifecycle.ViewModelProvider
19
- import com.reactnativereadium.epub.UserSettings
20
18
  import com.reactnativereadium.R
21
19
  import com.reactnativereadium.utils.toggleSystemUi
22
20
  import java.net.URL
@@ -24,11 +22,11 @@ import kotlinx.coroutines.delay
24
22
  import org.readium.r2.navigator.epub.EpubNavigatorFragment
25
23
  import org.readium.r2.navigator.ExperimentalDecorator
26
24
  import org.readium.r2.navigator.Navigator
27
- import org.readium.r2.shared.APPEARANCE_REF
25
+ import org.readium.r2.navigator.epub.EpubPreferences
26
+ import org.readium.r2.navigator.epub.EpubPreferencesSerializer
28
27
  import org.readium.r2.shared.publication.Locator
29
28
  import org.readium.r2.shared.publication.Publication
30
29
  import org.readium.r2.shared.ReadiumCSSName
31
- import org.readium.r2.shared.SCROLL_REF
32
30
 
33
31
  @OptIn(ExperimentalDecorator::class)
34
32
  class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listener {
@@ -38,13 +36,13 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene
38
36
  private lateinit var publication: Publication
39
37
  lateinit var navigatorFragment: EpubNavigatorFragment
40
38
  private lateinit var factory: ReaderViewModel.Factory
41
- private var initialSettingsMap: Map<String, Any>? = null
39
+ private var initialPreferencesJsonString: String? = null
42
40
 
43
41
  private lateinit var menuScreenReader: MenuItem
44
42
  private lateinit var menuSearch: MenuItem
45
43
  lateinit var menuSearchView: SearchView
46
44
 
47
- private lateinit var userSettings: UserSettings
45
+ private lateinit var userPreferences: EpubPreferences
48
46
  private var isScreenReaderVisible = false
49
47
  private var isSearchViewIconified = true
50
48
 
@@ -61,12 +59,16 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene
61
59
  )
62
60
  }
63
61
 
64
- fun updateSettingsFromMap(map: Map<String, Any>) {
65
- if (this::userSettings.isInitialized) {
66
- userSettings.updateSettingsFromMap(map)
67
- initialSettingsMap = null
62
+ fun updatePreferencesFromJsonString(serialisedPreferences: String) {
63
+ if (this::userPreferences.isInitialized) {
64
+ val serializer = EpubPreferencesSerializer()
65
+ this.userPreferences = serializer.deserialize(serialisedPreferences)
66
+ if (navigator is EpubNavigatorFragment) {
67
+ (navigator as EpubNavigatorFragment).submitPreferences(this.userPreferences)
68
+ }
69
+ initialPreferencesJsonString = null
68
70
  } else {
69
- initialSettingsMap = map
71
+ initialPreferencesJsonString = serialisedPreferences
70
72
  }
71
73
  }
72
74
 
@@ -86,12 +88,10 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene
86
88
  publication = it.publication
87
89
  }
88
90
 
89
- val baseUrl = checkNotNull(requireArguments().getString(BASE_URL_ARG))
90
91
 
91
92
  childFragmentManager.fragmentFactory =
92
93
  EpubNavigatorFragment.createFactory(
93
94
  publication = publication,
94
- baseUrl = baseUrl,
95
95
  initialLocator = model.initialLocation,
96
96
  listener = this,
97
97
  config = EpubNavigatorFragment.Configuration().apply {
@@ -124,28 +124,16 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene
124
124
 
125
125
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
126
126
  super.onViewCreated(view, savedInstanceState)
127
-
128
- val activity = requireActivity()
129
- userSettings = UserSettings(
130
- navigatorFragment.preferences,
131
- activity,
132
- publication.userSettingsUIPreset
133
- )
134
-
135
- // This is a hack to draw the right background color on top and bottom blank spaces
136
- navigatorFragment.lifecycleScope.launchWhenStarted {
137
- val appearancePref = navigatorFragment.preferences.getInt(APPEARANCE_REF, 0)
138
- val backgroundsColors = mutableListOf("#ffffff", "#faf4e8", "#000000")
139
- navigatorFragment.resourcePager.setBackgroundColor(Color.parseColor(backgroundsColors[appearancePref]))
140
- }
141
127
  }
142
128
 
143
129
  override fun onResume() {
144
130
  super.onResume()
145
131
  val activity = requireActivity()
146
132
 
147
- userSettings.resourcePager = navigatorFragment.resourcePager
148
- initialSettingsMap?.let { updateSettingsFromMap(it) }
133
+ if (!this::userPreferences.isInitialized) {
134
+ userPreferences = EpubPreferences()
135
+ }
136
+ initialPreferencesJsonString?.let { updatePreferencesFromJsonString(it)}
149
137
 
150
138
  // If TalkBack or any touch exploration service is activated we force scroll mode (and
151
139
  // override user preferences)
@@ -153,18 +141,14 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene
153
141
  isExploreByTouchEnabled = am.isTouchExplorationEnabled
154
142
 
155
143
  if (isExploreByTouchEnabled) {
156
- // Preset & preferences adapted
157
- publication.userSettingsUIPreset[ReadiumCSSName.ref(SCROLL_REF)] = true
158
- navigatorFragment.preferences.edit().putBoolean(SCROLL_REF, true).apply() //overriding user preferences
159
- userSettings.saveChanges()
160
-
161
- lifecycleScope.launchWhenResumed {
162
- delay(500)
163
- userSettings.updateViewCSS(SCROLL_REF)
164
- }
144
+ this.userPreferences = this.userPreferences.plus(
145
+ EpubPreferences(scroll = true)
146
+ )
165
147
  } else {
166
148
  if (publication.cssStyle != "cjk-vertical") {
167
- publication.userSettingsUIPreset.remove(ReadiumCSSName.ref(SCROLL_REF))
149
+ this.userPreferences = this.userPreferences.plus(
150
+ EpubPreferences(scroll = null)
151
+ )
168
152
  }
169
153
  }
170
154
  }
@@ -181,20 +165,14 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene
181
165
 
182
166
  companion object {
183
167
 
184
- private const val BASE_URL_ARG = "baseUrl"
185
-
186
168
  private const val SEARCH_FRAGMENT_TAG = "search"
187
169
 
188
170
  private const val IS_SCREEN_READER_VISIBLE_KEY = "isScreenReaderVisible"
189
171
 
190
172
  private const val IS_SEARCH_VIEW_ICONIFIED = "isSearchViewIconified"
191
173
 
192
- fun newInstance(baseUrl: URL): EpubReaderFragment {
193
- return EpubReaderFragment().apply {
194
- arguments = Bundle().apply {
195
- putString(BASE_URL_ARG, baseUrl.toString())
196
- }
197
- }
174
+ fun newInstance(): EpubReaderFragment {
175
+ return EpubReaderFragment()
198
176
  }
199
177
  }
200
178
  }
@@ -8,10 +8,8 @@ import com.reactnativereadium.utils.LinkOrLocator
8
8
  import java.io.File
9
9
  import java.io.IOException
10
10
  import java.net.ServerSocket
11
- import java.net.URL
12
11
  import org.readium.r2.shared.extensions.mediaType
13
12
  import org.readium.r2.shared.extensions.tryOrNull
14
- import org.readium.r2.shared.Injectable
15
13
  import org.readium.r2.shared.publication.Locator
16
14
  import org.readium.r2.shared.publication.asset.FileAsset
17
15
  import org.readium.r2.shared.publication.Publication
@@ -80,13 +78,11 @@ class ReaderService(
80
78
  sender = reactContext
81
79
  )
82
80
  .onSuccess {
83
- val url = prepareToServe(it)
84
- if (url != null) {
85
81
  val locator = locatorFromLinkOrLocator(initialLocation, it)
86
- val readerFragment = EpubReaderFragment.newInstance(url)
82
+ val readerFragment = EpubReaderFragment.newInstance()
87
83
  readerFragment.initFactory(it, locator)
88
84
  callback.invoke(readerFragment)
89
- }
85
+
90
86
  }
91
87
  .onFailure {
92
88
  tryOrNull { asset.file.delete() }
@@ -95,15 +91,6 @@ class ReaderService(
95
91
  }
96
92
  }
97
93
 
98
- private fun prepareToServe(publication: Publication): URL? {
99
- val userProperties =
100
- reactContext.filesDir.path + "/" + Injectable.Style.rawValue + "/UserProperties.json"
101
- return server.addPublication(
102
- publication,
103
- userPropertiesFile = File(userProperties)
104
- )
105
- }
106
-
107
94
  private fun startServer() {
108
95
  if (!server.isAlive) {
109
96
  try {
@@ -25,7 +25,7 @@ inline fun <reified T : Fragment> createFragmentFactory(crossinline factory: ()
25
25
  *
26
26
  * ```
27
27
  * supportFragmentManager.fragmentFactory = CompositeFragmentFactory(
28
- * EpubNavigatorFragment.createFactory(publication, baseUrl, initialLocator, this),
28
+ * EpubNavigatorFragment.createFactory(publication, initialLocator, this),
29
29
  * PdfNavigatorFragment.createFactory(publication, initialLocator, this)
30
30
  * )
31
31
  * ```
@@ -27,7 +27,7 @@ final class AppModule {
27
27
  fatalError("Can't start publication server")
28
28
  }
29
29
 
30
- reader = ReaderModule(delegate: self, resourcesServer: server)
30
+ reader = ReaderModule(delegate: self)
31
31
 
32
32
  // Set Readium 2's logging minimum level.
33
33
  R2EnableLog(withMinimumSeverityLevel: .debug)
@@ -0,0 +1,8 @@
1
+ //
2
+ // EPUBPreferences.swift
3
+ // react-native-readium
4
+ //
5
+ // Created by Christopher Wilkinson on 11/09/2023.
6
+ //
7
+
8
+ import Foundation
@@ -290,20 +290,14 @@ extension ReaderViewController: NavigatorDelegate {
290
290
 
291
291
  extension ReaderViewController: VisualNavigatorDelegate {
292
292
 
293
- func navigator(_ navigator: VisualNavigator, didTapAt point: CGPoint) {
294
- let viewport = navigator.view.bounds
295
- // Skips to previous/next pages if the tap is on the content edges.
296
- let thresholdRange = 0...(0.2 * viewport.width)
297
- var moved = false
298
- if thresholdRange ~= point.x {
299
- moved = navigator.goLeft(animated: false)
300
- } else if thresholdRange ~= (viewport.maxX - point.x) {
301
- moved = navigator.goRight(animated: false)
293
+ func navigator(_ navigator: VisualNavigator, didTapAt point: CGPoint) {
294
+ let moved = DirectionalNavigationAdapter(navigator: navigator).didTap(at: point)
295
+ if !moved {
296
+ toggleNavigationBar()
297
+ }
302
298
  }
303
-
304
- if !moved {
305
- toggleNavigationBar()
299
+
300
+ func navigator(_ navigator: VisualNavigator, didPressKey event: KeyEvent) {
301
+ DirectionalNavigationAdapter(navigator: navigator).didPressKey(event: event)
306
302
  }
307
- }
308
-
309
303
  }
@@ -1,19 +1,19 @@
1
1
  import UIKit
2
- import R2Shared
2
+ import R2Navigator
3
3
 
4
4
  class AssociatedColors {
5
5
 
6
- /// Get associated colors for a specific appearance setting
7
- /// - parameter appearance: The selected appearance
6
+ /// Get associated colors for a specific theme setting
7
+ /// - parameter theme: The selected theme
8
8
  /// - Returns: A tuple with a main color and a text color
9
- static func getColors(for appearance: UserProperty) -> (mainColor: UIColor, textColor: UIColor) {
9
+ static func getColors(for theme: Theme) -> (mainColor: UIColor, textColor: UIColor) {
10
10
  var mainColor, textColor: UIColor
11
11
 
12
- switch appearance.toString() {
13
- case "readium-sepia-on":
12
+ switch theme {
13
+ case .sepia:
14
14
  mainColor = UIColor.init(red: 250/255, green: 244/255, blue: 232/255, alpha: 1)
15
15
  textColor = UIColor.init(red: 18/255, green: 18/255, blue: 18/255, alpha: 1)
16
- case "readium-night-on":
16
+ case .dark:
17
17
  mainColor = UIColor.black
18
18
  textColor = UIColor.init(red: 254/255, green: 254/255, blue: 254/255, alpha: 1)
19
19
  default:
@@ -11,25 +11,24 @@ final class EPUBModule: ReaderFormatModule {
11
11
  self.delegate = delegate
12
12
  }
13
13
 
14
- var publicationFormats: [Publication.Format] {
15
- return [.epub, .webpub]
14
+ func supports(_ publication: Publication) -> Bool {
15
+ publication.conforms(to: .epub)
16
+ || publication.readingOrder.allAreHTML
16
17
  }
17
18
 
18
19
  func makeReaderViewController(
19
20
  for publication: Publication,
20
21
  locator: Locator?,
21
- bookId: String,
22
- resourcesServer: ResourcesServer
22
+ bookId: String
23
23
  ) throws -> ReaderViewController {
24
24
  guard publication.metadata.identifier != nil else {
25
25
  throw ReaderError.epubNotValid
26
26
  }
27
27
 
28
- let epubViewController = EPUBViewController(
28
+ let epubViewController = try EPUBViewController(
29
29
  publication: publication,
30
30
  locator: locator,
31
- bookId: bookId,
32
- resourcesServer: resourcesServer
31
+ bookId: bookId
33
32
  )
34
33
  epubViewController.moduleDelegate = delegate
35
34
  return epubViewController
@@ -1,19 +1,19 @@
1
1
  import UIKit
2
2
  import R2Shared
3
3
  import R2Navigator
4
+ import ReadiumAdapterGCDWebServer
4
5
 
5
6
  class EPUBViewController: ReaderViewController {
6
7
 
7
8
  init(
8
9
  publication: Publication,
9
10
  locator: Locator?,
10
- bookId: String,
11
- resourcesServer: ResourcesServer
12
- ) {
13
- let navigator = EPUBNavigatorViewController(
11
+ bookId: String
12
+ ) throws {
13
+ let navigator = try EPUBNavigatorViewController(
14
14
  publication: publication,
15
15
  initialLocation: locator,
16
- resourcesServer: resourcesServer
16
+ httpServer: GCDHTTPServer.shared
17
17
  )
18
18
 
19
19
  super.init(
@@ -33,13 +33,11 @@ class EPUBViewController: ReaderViewController {
33
33
  super.viewDidLoad()
34
34
 
35
35
  /// Set initial UI appearance.
36
- if let appearance = publication.userProperties.getProperty(reference: ReadiumCSSReference.appearance.rawValue) {
37
- setUIColor(for: appearance)
38
- }
36
+ setUIColor(for: epubNavigator.settings.theme)
39
37
  }
40
38
 
41
- internal func setUIColor(for appearance: UserProperty) {
42
- let colors = AssociatedColors.getColors(for: appearance)
39
+ internal func setUIColor(for theme: Theme) {
40
+ let colors = AssociatedColors.getColors(for: theme)
43
41
 
44
42
  navigator.view.backgroundColor = colors.mainColor
45
43
  view.backgroundColor = colors.mainColor
@@ -8,15 +8,14 @@ protocol ReaderFormatModule {
8
8
 
9
9
  var delegate: ReaderFormatModuleDelegate? { get }
10
10
 
11
- /// Publication types handled by this sub-module.
12
- var publicationFormats: [Publication.Format] { get }
11
+ /// Returns whether the given publication is supported by this module.
12
+ func supports(_ publication: Publication) -> Bool
13
13
 
14
14
  /// Creates the view controller to present the publication.
15
15
  func makeReaderViewController(
16
16
  for publication: Publication,
17
17
  locator: Locator?,
18
- bookId: String,
19
- resourcesServer: ResourcesServer
18
+ bookId: String
20
19
  ) throws -> ReaderViewController
21
20
 
22
21
  }
@@ -20,17 +20,14 @@ protocol ReaderModuleDelegate: ModuleDelegate {}
20
20
 
21
21
  final class ReaderModule: ReaderModuleAPI {
22
22
  weak var delegate: ReaderModuleDelegate?
23
- private let resourcesServer: ResourcesServer
24
23
 
25
24
  /// Sub-modules to handle different publication formats (eg. EPUB, CBZ)
26
25
  var formatModules: [ReaderFormatModule] = []
27
26
 
28
27
  init(
29
- delegate: ReaderModuleDelegate?,
30
- resourcesServer: ResourcesServer
28
+ delegate: ReaderModuleDelegate?
31
29
  ) {
32
30
  self.delegate = delegate
33
- self.resourcesServer = resourcesServer
34
31
 
35
32
  formatModules = [
36
33
  // CBZModule(delegate: self),
@@ -49,7 +46,7 @@ final class ReaderModule: ReaderModuleAPI {
49
46
  locator: Locator?
50
47
  ) -> ReaderViewController? {
51
48
  guard let module = self.formatModules.first(
52
- where:{ $0.publicationFormats.contains(publication.format) }
49
+ where:{ $0.supports(publication) }
53
50
  ) else {
54
51
  print("Unable to display the publication due to an unsupported format.")
55
52
  return nil
@@ -59,8 +56,7 @@ final class ReaderModule: ReaderModuleAPI {
59
56
  return try module.makeReaderViewController(
60
57
  for: publication,
61
58
  locator: locator,
62
- bookId: bookId,
63
- resourcesServer: resourcesServer
59
+ bookId: bookId
64
60
  )
65
61
  } catch {
66
62
  print("An unexpected error occurred when attempting to build the reader view.")
@@ -7,13 +7,11 @@ import UIKit
7
7
  final class ReaderService: Loggable {
8
8
  var app: AppModule?
9
9
  var streamer = Streamer()
10
- var publicationServer: PublicationServer?
11
10
  private var subscriptions = Set<AnyCancellable>()
12
11
 
13
12
  init() {
14
13
  do {
15
14
  self.app = try AppModule()
16
- self.publicationServer = PublicationServer()
17
15
  } catch {
18
16
  print("TODO: An error occurred instantiating the ReaderService")
19
17
  print(error)
@@ -29,11 +27,13 @@ final class ReaderService: Loggable {
29
27
  }
30
28
 
31
29
  let hasLocations = location?["locations"] != nil
30
+ let hasType = (location?["type"] as? String)?.isEmpty == false
32
31
  let hasChildren = location?["children"] != nil
33
- let hasHashHref = (location!["href"] as! String).contains("#")
32
+ let hasHashHref = (location?["href"] as? String)?.contains("#") == true
33
+ let hasTemplated = location?["templated"] != nil
34
34
 
35
35
  // check that we're not dealing with a Link
36
- if ((hasChildren || hasHashHref) && !hasLocations) {
36
+ if ((!hasType || hasChildren || hasHashHref || hasTemplated) && !hasLocations) {
37
37
  guard let publication = publication else {
38
38
  return nil
39
39
  }
@@ -65,7 +65,6 @@ final class ReaderService: Loggable {
65
65
  print(">>>>>>>>>>> TODO: handle me", error)
66
66
  },
67
67
  receiveValue: { pub in
68
- self.preparePresentation(of: pub)
69
68
  let locator: Locator? = ReaderService.locatorFromLocation(location, pub)
70
69
  let vc = reader.getViewController(
71
70
  for: pub,
@@ -139,18 +138,4 @@ final class ReaderService: Loggable {
139
138
  }
140
139
  return .just(publication)
141
140
  }
142
-
143
- private func preparePresentation(of publication: Publication) {
144
- if (self.publicationServer == nil) {
145
- log(.error, "Whoops")
146
- return
147
- }
148
-
149
- publicationServer?.removeAll()
150
- do {
151
- try publicationServer?.add(publication)
152
- } catch {
153
- log(.error, error)
154
- }
155
- }
156
141
  }