App.vue 5.52 KB
Newer Older
Mathias Goebel's avatar
Mathias Goebel committed
1
2
<template>
  <div id="q-app">
3
    <q-layout view="hHh lpr fFf">
4
      <Header v-if="config.headers.all"
5
        :collectiontitle="collectiontitle"
6
        :config="config"
7
8
        :itemurls="itemurls"
        :manifests="manifests"
9
        :pagelabel="pagelabel"
10
11
12
13
14
15
        :status="status"
      />

      <q-page-container>
        <router-view
          :collection="collection"
16
          :config="config"
17
          :contenturl="contenturl"
schneider210's avatar
schneider210 committed
18
          :fontsize="fontsize"
19
          :imageurl="imageurl"
20
          :language="itemlanguage"
21
          :manifests="manifests"
22
          :pagelabel="pagelabel"
23
          :request="request"
schneider210's avatar
schneider210 committed
24
          :status="status"
25
26
27
          :tree="tree"
        />
      </q-page-container>
28

29
30
31
      <Footer
        :standalone="config.standalone"
      />
32
    </q-layout>
Mathias Goebel's avatar
Mathias Goebel committed
33
34
35
36
  </div>
</template>

<script>
37
import Header from '@/components/quasar-header.vue';
38
import Footer from '@/components/quasar-footer.vue';
39

Mathias Goebel's avatar
Mathias Goebel committed
40
export default {
41
42
43
  name: 'Viewer',
  components: {
    Header,
44
    Footer,
45
46
47
48
  },
  data() {
    return {
      collection: {},
49
50
      collectiontitle: '',
      contenturl: '',
51
      config: {},
schneider210's avatar
schneider210 committed
52
      fontsize: 14,
53
      imageurl: '',
54
      itemlanguage: '',
55
56
57
      itemurl: '',
      itemurls: [],
      label: '',
58
      pagelabel: '',
59
      manifests: [],
schneider210's avatar
schneider210 committed
60
      status: {},
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
      tree: [],
    };
  },
  methods: {
    async request(url, responsetype = 'json') {
      const response = await fetch(url);
      const data = await (responsetype === 'text' ? response.text() : response.json());

      return data;
    },
    getCollection(url) {
      this.request(url)
        .then((data) => {
          this.collection = data;
          this.label = this.getLabel(data);

77
          this.tree.push({ label: this.label, labelKey: this.label, children: [] });
78
79
80
81
82
83
84
85

          if (Array.isArray(data.sequence)) {
            data.sequence.forEach((seq) => this.getManifest(seq.id));
          }
        });
    },
    getConfig() {
      this.config = JSON.parse(document.getElementById('emo-config').text);
schneider210's avatar
schneider210 committed
86
87
88
89

      if (Object.keys(this.config.panels).length) {
        this.status = this.config.panels;
      }
90
    },
91
    getItemData(url) {
92
93
      this.request(url)
        .then((data) => {
94
95
          this.collectiontitle = data.title;
          this.contenturl = data.content;
96
          this.imageurl = data.image && data.image.id ? data.image.id : '';
97
98
          this.itemlanguage = data.language;
          this.pagelabel = data.n ? data.n : 'No pagelabel :(';
99
100
101
102
103
104
105
106
107
108
109
110
111
        });
    },
    getItemIndex(nodelabel) {
      let idx = 0;
      this.itemurls.forEach((item, index) => {
        if (item === nodelabel) {
          idx = index;
        }
      });
      return idx;
    },
    getItemUrls(sequence, label) {
      const urls = [];
112
      let ctr = 0;
113

114
115
116
117
      sequence.forEach((obj) => {
        urls.push(
          {
            label: obj.id,
118
            labelKey: `${this.config.labels.item} ${ctr += 1}`,
119
120
121
122
123
124
            handler: (node) => {
              if (this.itemurl === node.label) {
                return;
              }
              this.$root.$emit('update-item', node.label);
              this.$root.$emit('update-item-index', this.getItemIndex(node.label));
125
              this.$root.$emit('update-sequence-index', this.getSequenceIndex(label));
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
            },
          },
        );
      });
      return urls;
    },
    getLabel(data) {
      if (Object.keys(this.collection).length) {
        return data.title && data.title[0].title ? data.title[0].title : data.label;
      }
      return data.label ? data.label : 'Manifest <small>(No label available)</small>';
    },
    getManifest(url) {
      this.request(url)
        .then((data) => {
          if (!Array.isArray(data.sequence)) {
            data.sequence = [data.sequence];
          }

          if (data.sequence[0] !== 'undefined') {
            data.sequence.map((seq) => this.itemurls.push(seq.id));
          }
          this.manifests.push(data);

          this.tree[0].children.push(
151
152
153
154
155
            {
              label: data.label,
              labelKey: data.label,
              children: this.getItemUrls(data.sequence, data.label),
            },
156
157
158
159
160
161
162
163
          );

          if (!this.label) {
            this.label = this.getLabel(data);
          }
          // make sure that urls are set just once on init
          if (!this.itemurl && data.sequence[0]) {
            this.itemurl = data.sequence[0].id;
164
            this.getItemData(data.sequence[0].id);
165
166
167
          }
        });
    },
168
    getSequenceIndex(label) {
169
170
      let index = 0;
      this.manifests.forEach((manifest, idx) => {
171
        if (manifest.label === label) {
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
          index = idx;
        }
      });
      return index;
    },
    init() {
      return this.config.entrypoint.match(/collection.json\s?$/)
        ? this.getCollection(this.config.entrypoint)
        : this.getManifest(this.config.entrypoint);
    },
  },
  created() {
    this.getConfig();
    this.init();

    this.itemurls.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
  },
  mounted() {
    this.$root.$on('update-item', (url) => {
      this.itemurl = url;
      this.$router.push({ query: { itemurl: url } });
      // NOTE: Set imageurl to an empty string. Otherwise, if there is no corresponding image,
      // the "preceding" image according to the "preceding" itemurl will be shown.
      this.imageurl = '';
196
      this.getItemData(url);
197
198
199
200
201
    });

    this.$root.$on('update-panel-status', (status) => {
      this.status = status;
    });
schneider210's avatar
schneider210 committed
202
203
204
    this.$root.$on('change-fontsize', (fontsize) => {
      this.fontsize = fontsize;
    });
205
  },
Mathias Goebel's avatar
Mathias Goebel committed
206
207
};
</script>