Edition.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <template>
  2. <MainContentLayout id="edition">
  3. <template v-if="!content" #header>
  4. <span>Loading ...</span>
  5. </template>
  6. <template #header>
  7. <h1>{{ title }}</h1>
  8. <p v-if="meta">{{ meta.author }}</p>
  9. <aside
  10. v-if="indexitem"
  11. class="index-tooltip"
  12. :style="{ top:tooltip_top + 'px' }"
  13. >
  14. <span v-if="indexitem == 'loading'">Loading ...</span>
  15. <template v-if="indexitem !== 'loading'">
  16. <h1 v-html="indexitem.title" />
  17. <p v-if="indexitem.birthDate" class="birthdeath">
  18. <time>{{ indexitem.birthDate }}</time>, <span class="place">{{ indexitem.birthPlace }}</span><br>
  19. <time>{{ indexitem.deathDate }}</time>, <span class="place">{{ indexitem.deathPlace }}</span>
  20. </p>
  21. <p v-if="indexitem.occupation" class="occupation">
  22. {{ indexitem.occupation }}
  23. </p>
  24. <p v-if="indexitem.type" class="type">
  25. {{ indexitem.type }}
  26. </p>
  27. </template>
  28. </aside>
  29. </template>
  30. <!-- default slot -->
  31. <div id="text">
  32. <template v-if="texts.length">
  33. <infinite-loading direction="top" @infinite="prevText" />
  34. <EdText
  35. v-for="text in texts"
  36. :key="text.content.uuid"
  37. :tei="text.content.tei"
  38. :uuid="text.content.uuid"
  39. @onHoverLink="onHoverLink"
  40. @onLeaveLink="onLeaveLink"
  41. />
  42. <infinite-loading @infinite="nextText" />
  43. </template>
  44. </div>
  45. <template #nav>
  46. <EdToc :toc="toc" />
  47. </template>
  48. </MainContentLayout>
  49. </template>
  50. <script>
  51. import { REST } from 'api/rest-axios'
  52. import { mapState, mapActions } from 'vuex'
  53. import MainContentLayout from '../components/Layouts/MainContentLayout'
  54. import EdText from '../components/Content/EdText'
  55. import EdToc from '../components/Content/EdToc'
  56. export default {
  57. name: 'Edition',
  58. metaInfo () {
  59. // console.log('metainfo', this.meta)
  60. return {
  61. title: this.metainfotitle
  62. }
  63. },
  64. components: {
  65. MainContentLayout,
  66. EdText,
  67. EdToc
  68. },
  69. data: () => ({
  70. toc: null,
  71. meta: null,
  72. editionid: null,
  73. textid: null,
  74. texts: [],
  75. metainfotitle: undefined,
  76. title: undefined,
  77. author: undefined,
  78. texttitle: undefined,
  79. //
  80. indexitem: null,
  81. tooltip_top: null
  82. }),
  83. computed: {
  84. ...mapState({
  85. editionslist: state => state.Corpus.editionslist,
  86. editionsbyuuid: state => state.Corpus.editionsbyuuid
  87. })
  88. },
  89. watch: {
  90. textid: function (newid, oldid) {
  91. console.log('textid watcher', this, oldid, newid)
  92. this.texts = []
  93. this.getTextContent(newid)
  94. },
  95. textdata: function (newtxtdata, oldtxtdata) {
  96. console.log('textdata watcher', oldtxtdata, newtxtdata)
  97. this.metainfotitle = `${this.title} ${newtxtdata.meta.title}`
  98. }
  99. },
  100. beforeCreate () {
  101. console.log('texts this.$route', this.$route)
  102. // http://localhost:8984/texts/gdpSauval1724/toc
  103. // get the edition's toc
  104. REST.get(`/texts/` + this.$route.params.id + `/toc`, {})
  105. .then(({ data }) => {
  106. console.log('texts/toc REST: data', data)
  107. this.meta = data.meta
  108. this.author = data.meta.author
  109. if (data.content) {
  110. if (Array.isArray(data.content)) {
  111. this.toc = data.content
  112. } else {
  113. this.toc = [data.content]
  114. }
  115. // if front page get the first item in toc
  116. if (!this.$route.params.textid) {
  117. // console.log('toc', this.toc)
  118. this.textid = this.toc[0].children[1].uuid
  119. }
  120. }
  121. })
  122. .catch((error) => {
  123. console.warn('Issue with locorum', error)
  124. Promise.reject(error)
  125. })
  126. },
  127. created () {
  128. // console.log('Edition this.$route.params.id', this.$route.params.id)
  129. this.editionid = this.$route.params.id
  130. // load editions list from Corpus Store if not exist
  131. if (!this.editionslist.length) {
  132. this.getCorpuses()
  133. // subsribe to store to get the editionbyuuid list
  134. // https://dev.to/viniciuskneves/watch-for-vuex-state-changes-2mgj
  135. this.unsubscribe = this.$store.subscribe((mutation, state) => {
  136. // console.log('Edition store subscribe', mutation.type)
  137. if (mutation.type === 'Corpus/setEditionsByUUID') {
  138. console.log('Edition state.Coprus.editionsbyuuid', this.editionid, state.Corpus.editionsbyuuid)
  139. // this.title = 'HoHoHo'
  140. this.title = this.metainfotitle = state.Corpus.editionsbyuuid[this.editionid].title
  141. }
  142. })
  143. } else {
  144. this.title = this.metainfotitle = this.editionsbyuuid[this.editionid].title
  145. }
  146. // get the text if textid available
  147. if (this.$route.params.textid) {
  148. this.textid = this.$route.params.textid
  149. }
  150. },
  151. beforeRouteUpdate (to, from, next) {
  152. // called when the route that renders this component has changed,
  153. // but this component is reused in the new route.
  154. // For example, for a route with dynamic params `/foo/:id`, when we
  155. // navigate between `/foo/1` and `/foo/2`, the same `Foo` component instance
  156. // will be reused, and this hook will be called when that happens.
  157. // has access to `this` component instance.
  158. // console.log('beforeRouteUpdate to', to)
  159. if (to.params.textid) {
  160. this.textid = to.params.textid
  161. }
  162. next()
  163. },
  164. methods: {
  165. ...mapActions({
  166. getCorpuses: 'Corpus/getCorpuses'
  167. }),
  168. getTextContent (textid, $state = null, direction = 'next') {
  169. console.log('getTextContent', textid)
  170. REST.get(`/items/${textid}`, {})
  171. .then(({ data }) => {
  172. console.log('text REST: data', data)
  173. if (direction === 'next') {
  174. this.texts.push(data)
  175. } else {
  176. this.texts.unshift(data)
  177. }
  178. if ($state) {
  179. $state.loaded()
  180. }
  181. })
  182. .catch((error) => {
  183. console.warn('Issue with getTextContent', error)
  184. Promise.reject(error)
  185. })
  186. },
  187. nextText ($state) {
  188. console.log('infinite loading nextText()', this.texts[this.texts.length - 1].content.itemAfterUuid, $state)
  189. if (this.texts[this.texts.length - 1].content.itemAfterUuid) {
  190. this.getTextContent(this.texts[this.texts.length - 1].content.itemAfterUuid, $state, 'next')
  191. } else {
  192. $state.complete()
  193. }
  194. },
  195. prevText ($state) {
  196. console.log('infinite loading prevText()', this.texts[0].content.itemBeforeUuid, $state)
  197. if (this.texts[0].content.itemBeforeUuid) {
  198. this.getTextContent(this.texts[0].content.itemBeforeUuid, $state, 'prev')
  199. } else {
  200. $state.complete()
  201. }
  202. },
  203. onHoverLink (elmt) {
  204. console.log('Edition onHoverLink(elmt)', elmt)
  205. this.tooltip_top = elmt.rect.top
  206. this.getIndexItem(elmt)
  207. },
  208. onLeaveLink () {
  209. console.log('Edition onLeaveLink()')
  210. this.indexitem = null
  211. },
  212. getIndexItem (item) {
  213. this.indexitem = 'loading'
  214. REST.get(`/index${item.index.charAt(0).toUpperCase()}${item.index.slice(1)}/${item.uuid}`, {})
  215. .then(({ data }) => {
  216. console.log('index tooltip REST: data', data)
  217. this.indexitem = data.content
  218. })
  219. .catch((error) => {
  220. console.warn('Issue with index tooltip rest', error)
  221. Promise.reject(error)
  222. this.indexitem = null
  223. })
  224. }
  225. }
  226. }
  227. </script>
  228. <style lang="scss" scoped>
  229. </style>