@saooti/octopus-sdk 1.0.0 → 29.0.2

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 (230) hide show
  1. package/README.md +73 -0
  2. package/index.d.ts +4 -0
  3. package/index.ts +12 -0
  4. package/package.json +61 -39
  5. package/public/css/fonts/saooti-ui.eot +0 -0
  6. package/public/css/fonts/saooti-ui.svg +30 -19
  7. package/public/css/fonts/saooti-ui.ttf +0 -0
  8. package/public/css/fonts/saooti-ui.woff +0 -0
  9. package/public/css/fonts/style.css +48 -5
  10. package/public/img/ACPM.png +0 -0
  11. package/public/img/article.png +0 -0
  12. package/src/App.vue +97 -31
  13. package/src/api/comments.ts +3 -1
  14. package/src/api/emissions.ts +5 -2
  15. package/src/api/initialize.ts +3 -2
  16. package/src/api/podcasts.ts +5 -2
  17. package/src/api/profile.ts +4 -2
  18. package/src/api/studio.ts +12 -1
  19. package/src/assets/bootstrap-diff.scss +265 -0
  20. package/src/assets/form.scss +23 -0
  21. package/src/assets/general.scss +47 -20
  22. package/src/assets/modal.scss +9 -10
  23. package/src/assets/multiselect.scss +19 -2
  24. package/src/assets/octopus-library.scss +16 -4
  25. package/src/assets/share.scss +343 -0
  26. package/src/components/display/aggregator/RssSection.vue +4 -4
  27. package/src/components/display/categories/CategoryChooser.vue +152 -105
  28. package/src/components/display/categories/CategoryFilter.vue +108 -0
  29. package/src/components/display/categories/CategoryList.vue +138 -109
  30. package/src/components/display/comments/AddCommentModal.vue +104 -87
  31. package/src/components/display/comments/CommentInput.vue +137 -118
  32. package/src/components/display/comments/CommentItem.vue +155 -137
  33. package/src/components/display/comments/CommentList.vue +142 -120
  34. package/src/components/display/comments/CommentParentInfo.vue +39 -35
  35. package/src/components/display/comments/CommentPlayer.vue +54 -48
  36. package/src/components/display/comments/CommentSection.vue +57 -58
  37. package/src/components/display/edit/EditBox.vue +4 -4
  38. package/src/components/display/edit/EditCommentBox.vue +25 -31
  39. package/src/components/display/emission/EmissionChooser.vue +82 -80
  40. package/src/components/display/emission/EmissionInlineList.vue +118 -105
  41. package/src/components/display/emission/EmissionItem.vue +66 -167
  42. package/src/components/display/emission/EmissionList.vue +96 -122
  43. package/src/components/display/emission/EmissionPlayerItem.vue +131 -126
  44. package/src/components/display/filter/AdvancedSearch.vue +306 -372
  45. package/src/components/display/filter/CategoryFilter.vue +117 -0
  46. package/src/components/display/filter/MonetizableFilter.vue +24 -10
  47. package/src/components/display/filter/ProductorSearch.vue +131 -135
  48. package/src/components/display/filter/RubriqueChoice.vue +104 -0
  49. package/src/components/display/filter/RubriqueFilter.vue +235 -0
  50. package/src/components/display/live/CountDown.vue +30 -29
  51. package/src/components/display/live/LiveHorizontalList.vue +40 -34
  52. package/src/components/display/live/LiveItem.vue +146 -158
  53. package/src/components/display/live/LiveList.vue +167 -154
  54. package/src/components/display/organisation/OrganisationChooser.vue +125 -124
  55. package/src/components/display/organisation/OrganisationChooserLight.vue +40 -47
  56. package/src/components/display/participant/ParticipantItem.vue +92 -108
  57. package/src/components/display/participant/ParticipantList.vue +76 -69
  58. package/src/components/display/playlist/PlaylistItem.vue +45 -56
  59. package/src/components/display/playlist/PlaylistList.vue +57 -48
  60. package/src/components/display/playlist/PodcastList.vue +94 -70
  61. package/src/components/display/podcasts/AnimatorsItem.vue +26 -23
  62. package/src/components/display/podcasts/ParticipantDescription.vue +115 -0
  63. package/src/components/display/podcasts/PodcastFilterList.vue +84 -85
  64. package/src/components/display/podcasts/PodcastImage.vue +244 -208
  65. package/src/components/display/podcasts/PodcastInlineList.vue +145 -207
  66. package/src/components/display/podcasts/PodcastItem.vue +150 -132
  67. package/src/components/display/podcasts/PodcastList.vue +89 -110
  68. package/src/components/display/podcasts/TagList.vue +23 -16
  69. package/src/components/display/rubriques/RubriqueChooser.vue +137 -123
  70. package/src/components/display/rubriques/RubriqueList.vue +227 -0
  71. package/src/components/display/sharing/PlayerParameters.vue +154 -106
  72. package/src/components/display/sharing/QrCode.vue +58 -0
  73. package/src/components/display/sharing/ShareButtons.vue +214 -92
  74. package/src/components/display/sharing/ShareDistribution.vue +110 -121
  75. package/src/components/display/sharing/SharePlayer.vue +245 -190
  76. package/src/components/display/sharing/SubscribeButtons.vue +130 -66
  77. package/src/components/display/studio/RecordingItemButton.vue +4 -4
  78. package/src/components/misc/ErrorMessage.vue +21 -16
  79. package/src/components/misc/Footer.vue +131 -66
  80. package/src/components/misc/HomeDropdown.vue +166 -123
  81. package/src/components/misc/LeftMenu.vue +151 -134
  82. package/src/components/misc/Player.vue +332 -328
  83. package/src/components/misc/Snackbar.vue +27 -29
  84. package/src/components/misc/TopBar.vue +204 -174
  85. package/src/components/misc/modal/ClipboardModal.vue +46 -26
  86. package/src/components/misc/modal/MessageModal.vue +67 -51
  87. package/src/components/misc/modal/NewsletterModal.vue +179 -136
  88. package/src/components/misc/modal/QrCodeModal.vue +83 -0
  89. package/src/components/misc/modal/ShareModalPlayer.vue +133 -74
  90. package/src/components/mixins/functions.ts +21 -18
  91. package/src/components/mixins/init.ts +24 -0
  92. package/src/components/mixins/organisationFilter.ts +24 -0
  93. package/src/components/pages/Category.vue +26 -26
  94. package/src/components/pages/Emission.vue +120 -92
  95. package/src/components/pages/Emissions.vue +109 -86
  96. package/src/components/pages/Home.vue +70 -16
  97. package/src/components/pages/Lives.vue +57 -47
  98. package/src/components/pages/Participant.vue +93 -77
  99. package/src/components/pages/Participants.vue +44 -31
  100. package/src/components/pages/Playlist.vue +63 -52
  101. package/src/components/pages/Playlists.vue +41 -39
  102. package/src/components/pages/Podcast.vue +265 -251
  103. package/src/components/pages/Podcasts.vue +135 -104
  104. package/src/components/pages/Rubrique.vue +25 -19
  105. package/src/components/pages/Search.vue +71 -67
  106. package/src/helper/dom.ts +2 -2
  107. package/src/helper/duration.ts +18 -8
  108. package/src/locale/educationen.ts +14 -0
  109. package/src/locale/en.ts +299 -1
  110. package/src/locale/fr.ts +25 -10
  111. package/src/locale/messages.ts +3 -2
  112. package/src/main.ts +54 -32
  113. package/src/router/router.ts +184 -159
  114. package/src/shims-tsx.d.ts +13 -0
  115. package/src/shims-vue-recaptcha-v3.d.ts +9 -0
  116. package/src/shims-vue.d.ts +5 -6
  117. package/src/store/AppStore.ts +36 -171
  118. package/src/store/class/category.ts +8 -0
  119. package/src/store/class/comment.ts +17 -0
  120. package/src/store/class/conference.ts +27 -0
  121. package/src/store/class/customPlayer.ts +8 -0
  122. package/src/store/class/emission.ts +20 -0
  123. package/src/store/class/fetchParam.ts +16 -0
  124. package/src/store/class/media.ts +13 -0
  125. package/src/store/class/organisation.ts +19 -0
  126. package/src/store/class/participant.ts +12 -0
  127. package/src/store/class/person.ts +13 -0
  128. package/src/store/class/player.ts +12 -0
  129. package/src/store/class/playlist.ts +15 -0
  130. package/src/store/class/podcast.ts +37 -0
  131. package/src/store/class/rubriquage.ts +9 -0
  132. package/src/store/class/rubriquageFilter.ts +5 -0
  133. package/src/store/class/rubrique.ts +8 -0
  134. package/src/store/paramStore.ts +70 -29
  135. package/src/store/typeAppStore.ts +171 -237
  136. package/src/vuex-shim.d.ts +8 -0
  137. package/tsconfig.json +4 -0
  138. package/vue.config.js +14 -0
  139. package/public/img/ACPM.PNG +0 -0
  140. package/src/assets/bootstrap_scss/_alert.scss +0 -51
  141. package/src/assets/bootstrap_scss/_badge.scss +0 -54
  142. package/src/assets/bootstrap_scss/_breadcrumb.scss +0 -42
  143. package/src/assets/bootstrap_scss/_button-group.scss +0 -164
  144. package/src/assets/bootstrap_scss/_buttons.scss +0 -291
  145. package/src/assets/bootstrap_scss/_card.scss +0 -278
  146. package/src/assets/bootstrap_scss/_carousel.scss +0 -197
  147. package/src/assets/bootstrap_scss/_close.scss +0 -41
  148. package/src/assets/bootstrap_scss/_code.scss +0 -48
  149. package/src/assets/bootstrap_scss/_custom-forms.scss +0 -522
  150. package/src/assets/bootstrap_scss/_dropdown.scss +0 -201
  151. package/src/assets/bootstrap_scss/_forms.scss +0 -352
  152. package/src/assets/bootstrap_scss/_functions.scss +0 -134
  153. package/src/assets/bootstrap_scss/_grid.scss +0 -69
  154. package/src/assets/bootstrap_scss/_images.scss +0 -42
  155. package/src/assets/bootstrap_scss/_input-group.scss +0 -191
  156. package/src/assets/bootstrap_scss/_jumbotron.scss +0 -17
  157. package/src/assets/bootstrap_scss/_list-group.scss +0 -158
  158. package/src/assets/bootstrap_scss/_media.scss +0 -8
  159. package/src/assets/bootstrap_scss/_mixins.scss +0 -47
  160. package/src/assets/bootstrap_scss/_modal.scss +0 -243
  161. package/src/assets/bootstrap_scss/_nav.scss +0 -120
  162. package/src/assets/bootstrap_scss/_navbar.scss +0 -324
  163. package/src/assets/bootstrap_scss/_pagination.scss +0 -74
  164. package/src/assets/bootstrap_scss/_popover.scss +0 -170
  165. package/src/assets/bootstrap_scss/_print.scss +0 -141
  166. package/src/assets/bootstrap_scss/_progress.scss +0 -46
  167. package/src/assets/bootstrap_scss/_reboot.scss +0 -482
  168. package/src/assets/bootstrap_scss/_root.scss +0 -20
  169. package/src/assets/bootstrap_scss/_spinners.scss +0 -55
  170. package/src/assets/bootstrap_scss/_tables.scss +0 -185
  171. package/src/assets/bootstrap_scss/_toasts.scss +0 -44
  172. package/src/assets/bootstrap_scss/_tooltip.scss +0 -115
  173. package/src/assets/bootstrap_scss/_transitions.scss +0 -20
  174. package/src/assets/bootstrap_scss/_type.scss +0 -125
  175. package/src/assets/bootstrap_scss/_utilities.scss +0 -17
  176. package/src/assets/bootstrap_scss/_variables.scss +0 -1145
  177. package/src/assets/bootstrap_scss/bootstrap-grid.scss +0 -29
  178. package/src/assets/bootstrap_scss/bootstrap-reboot.scss +0 -12
  179. package/src/assets/bootstrap_scss/bootstrap.scss +0 -44
  180. package/src/assets/bootstrap_scss/mixins/_alert.scss +0 -13
  181. package/src/assets/bootstrap_scss/mixins/_background-variant.scss +0 -22
  182. package/src/assets/bootstrap_scss/mixins/_badge.scss +0 -17
  183. package/src/assets/bootstrap_scss/mixins/_border-radius.scss +0 -63
  184. package/src/assets/bootstrap_scss/mixins/_box-shadow.scss +0 -20
  185. package/src/assets/bootstrap_scss/mixins/_breakpoints.scss +0 -123
  186. package/src/assets/bootstrap_scss/mixins/_buttons.scss +0 -110
  187. package/src/assets/bootstrap_scss/mixins/_caret.scss +0 -62
  188. package/src/assets/bootstrap_scss/mixins/_clearfix.scss +0 -7
  189. package/src/assets/bootstrap_scss/mixins/_deprecate.scss +0 -10
  190. package/src/assets/bootstrap_scss/mixins/_float.scss +0 -14
  191. package/src/assets/bootstrap_scss/mixins/_forms.scss +0 -177
  192. package/src/assets/bootstrap_scss/mixins/_gradients.scss +0 -45
  193. package/src/assets/bootstrap_scss/mixins/_grid-framework.scss +0 -71
  194. package/src/assets/bootstrap_scss/mixins/_grid.scss +0 -69
  195. package/src/assets/bootstrap_scss/mixins/_hover.scss +0 -37
  196. package/src/assets/bootstrap_scss/mixins/_image.scss +0 -36
  197. package/src/assets/bootstrap_scss/mixins/_list-group.scss +0 -21
  198. package/src/assets/bootstrap_scss/mixins/_lists.scss +0 -7
  199. package/src/assets/bootstrap_scss/mixins/_nav-divider.scss +0 -11
  200. package/src/assets/bootstrap_scss/mixins/_pagination.scss +0 -22
  201. package/src/assets/bootstrap_scss/mixins/_reset-text.scss +0 -17
  202. package/src/assets/bootstrap_scss/mixins/_resize.scss +0 -6
  203. package/src/assets/bootstrap_scss/mixins/_screen-reader.scss +0 -34
  204. package/src/assets/bootstrap_scss/mixins/_size.scss +0 -7
  205. package/src/assets/bootstrap_scss/mixins/_table-row.scss +0 -39
  206. package/src/assets/bootstrap_scss/mixins/_text-emphasis.scss +0 -17
  207. package/src/assets/bootstrap_scss/mixins/_text-hide.scss +0 -11
  208. package/src/assets/bootstrap_scss/mixins/_text-truncate.scss +0 -8
  209. package/src/assets/bootstrap_scss/mixins/_transition.scss +0 -16
  210. package/src/assets/bootstrap_scss/mixins/_visibility.scss +0 -8
  211. package/src/assets/bootstrap_scss/utilities/_align.scss +0 -8
  212. package/src/assets/bootstrap_scss/utilities/_background.scss +0 -19
  213. package/src/assets/bootstrap_scss/utilities/_borders.scss +0 -75
  214. package/src/assets/bootstrap_scss/utilities/_clearfix.scss +0 -3
  215. package/src/assets/bootstrap_scss/utilities/_display.scss +0 -26
  216. package/src/assets/bootstrap_scss/utilities/_embed.scss +0 -39
  217. package/src/assets/bootstrap_scss/utilities/_flex.scss +0 -51
  218. package/src/assets/bootstrap_scss/utilities/_float.scss +0 -11
  219. package/src/assets/bootstrap_scss/utilities/_overflow.scss +0 -5
  220. package/src/assets/bootstrap_scss/utilities/_position.scss +0 -32
  221. package/src/assets/bootstrap_scss/utilities/_screenreaders.scss +0 -11
  222. package/src/assets/bootstrap_scss/utilities/_shadows.scss +0 -6
  223. package/src/assets/bootstrap_scss/utilities/_sizing.scss +0 -20
  224. package/src/assets/bootstrap_scss/utilities/_spacing.scss +0 -73
  225. package/src/assets/bootstrap_scss/utilities/_stretched-link.scss +0 -19
  226. package/src/assets/bootstrap_scss/utilities/_text.scss +0 -72
  227. package/src/assets/bootstrap_scss/utilities/_visibility.scss +0 -13
  228. package/src/assets/bootstrap_scss/vendor/_rfs.scss +0 -204
  229. package/src/shims-vuex.d.ts +0 -7
  230. package/src/views/Home.vue +0 -18
@@ -1,17 +1,17 @@
1
1
  <template>
2
2
  <div
3
3
  class="w-100 transition-height bg-dark"
4
- v-bind:style="{ height: playerHeight }"
4
+ :style="{ height: playerHeight }"
5
5
  >
6
6
  <div
7
7
  class="player-container"
8
- v-bind:style="{ height: playerHeight }"
8
+ :style="{ height: playerHeight }"
9
9
  @transitionend="onHidden"
10
10
  >
11
11
  <div
12
+ v-if="isBarTop"
12
13
  class="progress secondary-bg c-hand"
13
14
  @mouseup="seekTo"
14
- v-if="isBarTop"
15
15
  >
16
16
  <div
17
17
  class="progress-bar primary-bg"
@@ -20,25 +20,26 @@
20
20
  aria-valuemin="0"
21
21
  aria-valuemax="100"
22
22
  :style="'width: ' + percentProgress + '%'"
23
- ></div>
24
- <div class="player-progress-border"></div>
23
+ />
24
+ <div class="player-progress-border" />
25
25
  </div>
26
26
  <div
27
- class="d-flex align-items-center justify-center flex-grow pr-5 pl-5"
28
27
  v-if="display"
28
+ class="d-flex align-items-center justify-center flex-grow pe-5 ps-5"
29
29
  >
30
30
  <audio
31
+ v-if="!live"
31
32
  id="audio-player"
32
- v-bind:src="audioUrl"
33
+ :src="audioUrl"
33
34
  autoplay
34
35
  @timeupdate="onTimeUpdate"
35
36
  @ended="onFinished"
36
37
  @playing="onPlay"
37
38
  @durationChange="onTimeUpdate"
38
39
  @error="onError"
39
- v-if="!live"
40
40
  />
41
41
  <audio
42
+ v-else
42
43
  id="audio-player"
43
44
  src
44
45
  @timeupdate="onTimeUpdate"
@@ -46,20 +47,22 @@
46
47
  @playing="onPlay"
47
48
  @durationChange="onTimeUpdate"
48
49
  @error="onError"
49
- v-else
50
50
  />
51
- <router-link :to="podcastShareUrl" v-if="isImage && podcastImage">
51
+ <router-link
52
+ v-if="isImage && podcastImage"
53
+ :to="podcastShareUrl"
54
+ >
52
55
  <img
53
- v-bind:src="podcastImage"
56
+ :src="podcastImage"
54
57
  :alt="$t('Podcast image')"
55
58
  class="player-image c-hand"
56
- />
59
+ >
57
60
  </router-link>
58
61
 
59
62
  <div
60
63
  v-if="!playerError"
61
64
  class="play-button-box"
62
- v-bind:class="{
65
+ :class="{
63
66
  'primary-bg': !isLoading,
64
67
  'text-light': !isLoading,
65
68
  }"
@@ -68,13 +71,13 @@
68
71
  <div
69
72
  class="text-light"
70
73
  :aria-label="$t('Play')"
71
- v-bind:class="{
74
+ :class="{
72
75
  saooti: isPlaying || isPaused,
73
76
  'saooti-play2-bounty': isPaused,
74
77
  'saooti-pause-bounty': isPlaying,
75
78
  loading: isLoading,
76
79
  }"
77
- ></div>
80
+ />
78
81
  </div>
79
82
  <div
80
83
  v-if="(isPlaying || isPaused) && (media || isStop)"
@@ -84,24 +87,33 @@
84
87
  <div
85
88
  class="text-light saooti-stop-bounty"
86
89
  :aria-label="$t('Stop')"
87
- ></div>
90
+ />
88
91
  </div>
89
92
  <div class="text-light player-grow-content">
90
93
  <div class="d-flex">
91
- <div class="text-warning player-title ml-2 mr-2" v-if="playerError">
94
+ <div
95
+ v-if="playerError"
96
+ class="text-warning player-title ms-2 me-2"
97
+ >
92
98
  {{ $t('Podcast play error') + ' - ' }}
93
99
  </div>
94
- <div class="flex-grow player-title">{{ podcastTitle }}</div>
95
- <div v-if="!playerError" v-show="!isBarTop" class="hide-phone">
100
+ <div class="flex-grow player-title">
101
+ {{ podcastTitle }}
102
+ </div>
103
+ <div
104
+ v-if="!playerError"
105
+ v-show="!isBarTop"
106
+ class="hide-phone"
107
+ >
96
108
  {{ playedTime }} / {{ totalTime }}
97
109
  </div>
98
110
  </div>
99
111
  <div
100
- class="progress c-hand custom-bg-darkgrey"
101
- @mouseup="seekTo"
102
- style="height: 3px;"
103
112
  v-if="!playerError"
104
113
  v-show="!isBarTop"
114
+ class="progress c-hand custom-bg-darkgrey"
115
+ style="height: 3px;"
116
+ @mouseup="seekTo"
105
117
  >
106
118
  <div
107
119
  class="progress-bar custom-bg-grey"
@@ -110,7 +122,7 @@
110
122
  aria-valuemin="0"
111
123
  aria-valuemax="100"
112
124
  :style="'width: ' + percentLiveProgress + '%'"
113
- ></div>
125
+ />
114
126
  <div
115
127
  class="progress-bar primary-bg"
116
128
  role="progressbar"
@@ -118,294 +130,157 @@
118
130
  aria-valuemin="0"
119
131
  aria-valuemax="100"
120
132
  :style="'width: ' + percentProgress + '%'"
121
- ></div>
133
+ />
122
134
  <div
123
- class="progress-bar progress-bar-duration bg-danger"
124
135
  v-if="displayAlertBar"
136
+ class="progress-bar progress-bar-duration bg-danger"
125
137
  :style="'left: ' + durationLivePosition + '%'"
126
- ></div>
138
+ />
127
139
  </div>
128
140
  <CommentPlayer
129
141
  v-if="showTimeline"
130
- :totalTime="totalSecondes"
142
+ :total-time="totalSecondes"
131
143
  :comments="comments"
132
144
  />
133
145
  </div>
134
146
  <div
147
+ v-if="0 !== comments.length && !isPodcastmaker"
135
148
  class="timeline-button"
136
- v-if="0 !== comments.length"
137
149
  @click="showTimeline = !showTimeline"
138
150
  >
139
151
  <div
140
152
  class="saooti-arrow_down saooti-arrow_down-margin"
141
153
  :class="showTimeline ? '' : 'arrow-transform'"
142
- ></div>
154
+ />
143
155
  <div>Timeline</div>
144
156
  </div>
145
157
  <div
146
- class="d-flex text-light align-items-center hide-phone"
147
158
  v-if="isClock"
159
+ class="d-flex text-light align-items-center hide-phone"
148
160
  >
149
- <div class="saooti-clock-stud m-2"></div>
161
+ <div class="saooti-clock-stud m-2" />
150
162
  <div>{{ actualTime }}</div>
151
163
  </div>
152
164
  </div>
153
165
  </div>
154
166
  </div>
155
167
  </template>
156
- <style lang="scss">
157
- @import '../../sass/_variables.scss';
158
-
159
- .play-button-box {
160
- height: 2.5rem;
161
- width: 2.5rem;
162
- display: flex;
163
- align-items: center;
164
- justify-content: center;
165
- margin: 0 0.5rem;
166
- border-radius: 50%;
167
- font-size: 1.2rem;
168
- flex-shrink: 0;
169
- cursor: pointer;
170
- }
171
-
172
- .player-container {
173
- position: fixed;
174
- overflow: hidden;
175
- z-index: 12;
176
- width: 100%;
177
- bottom: 0;
178
- display: flex;
179
- flex-direction: column;
180
- transition: height 1s;
181
- background: #282828 !important;
182
- max-width: 100%;
183
- font-size: 1rem;
184
-
185
- .player-image {
186
- border-radius: 0.2rem;
187
- height: 2.4rem;
188
- width: 2.4rem;
189
- }
190
- .player-progress-border {
191
- height: 10px;
192
- width: 3px;
193
- background: black;
194
- }
195
- .progress {
196
- align-items: flex-end;
197
- height: 10px;
198
- position: relative;
199
- }
200
- .progress-bar-duration {
201
- width: 10px;
202
- }
203
- .progress-bar {
204
- height: 4px;
205
- position: absolute;
206
- }
207
-
208
- .progress.custom-bg-darkgrey {
209
- background: #555;
210
- }
211
-
212
- .progress-bar.custom-bg-grey {
213
- background: #e9ecef;
214
- }
215
-
216
- .player-title,
217
- .hide-phone {
218
- font-size: 0.8rem;
219
- margin: 0 0 5px 0;
220
- }
221
- .player-grow-content {
222
- display: flex;
223
- flex-grow: 1;
224
- flex-direction: column;
225
- flex-shrink: 1;
226
- flex-basis: 20px;
227
- overflow: hidden;
228
- }
229
- .player-title {
230
- font-size: 0.8rem;
231
- margin: 0 0 5px 0;
232
- }
233
-
234
- .hide-phone {
235
- font-size: 0.8rem;
236
- margin: 0 0 5px 0;
237
- }
238
- .timeline-button {
239
- background: black;
240
- padding: 0.1rem;
241
- border-radius: 50%;
242
- width: 70px;
243
- height: 70px;
244
- font-size: 0.7rem;
245
- font-weight: bold;
246
- justify-content: center;
247
- display: flex;
248
- flex-direction: column;
249
- align-items: center;
250
- cursor: pointer;
251
- color: $octopus-primary-color;
252
- margin-left: 0.5rem;
253
- @media (max-width: 960px) {
254
- display: none;
255
- }
256
- }
257
- }
258
- /** PHONES*/
259
- @media (max-width: 450px) {
260
- .player-container {
261
- .player-image {
262
- height: 2rem;
263
- width: 2rem;
264
- }
265
- }
266
- }
267
-
268
- @media (max-width: 960px) {
269
- .player-container {
270
- .d-flex {
271
- @media (max-width: 960px) {
272
- flex-wrap: nowrap !important;
273
- }
274
- }
275
- .player-title {
276
- font-size: 12px;
277
- overflow: hidden;
278
- white-space: nowrap;
279
- text-overflow: ellipsis;
280
- }
281
- }
282
- }
283
- </style>
284
168
 
285
169
  <script lang="ts">
286
170
  import { mapState } from 'vuex';
287
171
  import { state } from '../../store/paramStore';
288
172
  import DurationHelper from '../../helper/duration';
289
- import CommentPlayer from '../display/comments/CommentPlayer.vue';
290
173
  const octopusApi = require('@saooti/octopus-api');
291
- import Hls from 'hls.js';
174
+ let Hls: any= null;
292
175
 
293
176
  const moment = require('moment');
294
177
  //const axios = require("axios");
295
-
296
- import { defineComponent } from 'vue'
178
+ import { CommentPodcast } from '@/store/class/comment';
179
+ import { cookies } from '../mixins/functions';
180
+ import { StoreState } from '@/store/typeAppStore';
181
+ import { defineComponent, defineAsyncComponent } from 'vue';
182
+ const CommentPlayer = defineAsyncComponent(() => import('../display/comments/CommentPlayer.vue'));
297
183
  export default defineComponent({
298
184
  name: 'Player',
299
185
 
300
186
  components: {
301
187
  CommentPlayer,
302
188
  },
303
-
189
+ mixins:[cookies],
304
190
  emits: ['hide'],
305
191
 
306
- mounted() {
307
- moment.locale('fr');
308
- if (this.isClock) {
309
- setInterval(() => {
310
- this.actualTime = moment(new Date()).format('HH:mm:ss');
311
- }, 1000);
312
- }
313
- window.addEventListener('beforeunload', this.endListeningProgress);
314
- this.watchPlayerStatus();
315
- },
316
-
317
192
  data() {
318
193
  return {
319
- forceHide: false,
320
- actualTime: '',
321
- listenTime: 0,
322
- notListenTime: 0,
323
- lastSend: 0,
324
- downloadId: null,
325
- playerError: false,
326
- listenError: false,
327
- percentLiveProgress: 0,
328
- durationLivePosition: 0,
329
- displayAlertBar: false,
330
- hlsReady: false,
331
- comments: [] as any,
332
- showTimeline: false,
194
+ forceHide: false as boolean,
195
+ actualTime: '' as string,
196
+ listenTime: 0 as number,
197
+ notListenTime: 0 as number,
198
+ lastSend: 0 as number,
199
+ downloadId: null as any,
200
+ playerError: false as boolean,
201
+ listenError: false as boolean,
202
+ percentLiveProgress: 0 as number,
203
+ durationLivePosition: 0 as number,
204
+ displayAlertBar: false as boolean,
205
+ hlsReady: false as boolean,
206
+ comments: [] as Array<CommentPodcast>,
207
+ showTimeline: false as boolean,
333
208
  };
334
209
  },
335
210
 
336
211
  computed: {
337
- isPlaying():boolean {
212
+ isPodcastmaker(): boolean {
213
+ return state.generalParameters.podcastmaker;
214
+ },
215
+ isPlaying(): boolean {
338
216
  return 'PLAYING' === this.status;
339
217
  },
340
- isPaused():boolean {
218
+ isPaused(): boolean {
341
219
  return 'PAUSED' === this.status;
342
220
  },
343
- isLoading():boolean {
221
+ isLoading(): boolean {
344
222
  return 'LOADING' === this.status;
345
223
  },
346
- isImage() {
224
+ isImage(): string {
347
225
  return state.player.image;
348
226
  },
349
- isEmissionName() {
227
+ isEmissionName(): string {
350
228
  return state.player.emissionName;
351
229
  },
352
- isClock() {
230
+ isClock(): boolean {
353
231
  return state.player.clock;
354
232
  },
355
- isBarTop() {
233
+ isBarTop(): boolean {
356
234
  return state.player.barTop;
357
235
  },
358
236
  ...mapState({
359
- display: (state:any) => 'STOPPED' !== state.player.status,
360
- playerHeight(state:any) {
237
+ display: (state: StoreState) => 'STOPPED' !== state.player.status,
238
+ playerHeight(state: StoreState) {
361
239
  if ('STOPPED' === state.player.status || this.forceHide) return 0;
362
240
  if (window.innerWidth > 450 && !this.showTimeline) return '5rem';
363
241
  if (window.innerWidth > 450 && this.showTimeline) return '6rem';
364
242
  return '3.5rem';
365
243
  },
366
- status: (state:any) => state.player.status,
367
- podcast: (state:any) => state.player.podcast,
368
- media: (state:any) => state.player.media,
369
- live: (state:any) => state.player.live,
370
- volume: (state:any) => state.player.volume,
371
- isStop: (state:any) => state.player.stop,
372
- commentsLoaded: (state:any) => state.comments.loadedComments,
373
-
374
- podcastImage: (state:any) => {
244
+ status: (state: StoreState) => state.player.status,
245
+ podcast: (state: StoreState) => state.player.podcast,
246
+ media: (state: StoreState) => state.player.media,
247
+ live: (state: StoreState) => state.player.live,
248
+ volume: (state: StoreState) => state.player.volume,
249
+ isStop: (state: StoreState) => state.player.stop,
250
+ commentsLoaded: (state: StoreState) => state.comments.loadedComments,
251
+ podcastImage: (state: StoreState) => {
375
252
  if (state.player.podcast) return state.player.podcast.imageUrl;
376
253
  return '';
377
254
  },
378
-
379
- playedTime: (state:any) => {
380
- if (state.player.elapsed > 0 && state.player.total > 0) {
255
+ playedTime: (state: StoreState) => {
256
+ if (state.player.elapsed && state.player.elapsed > 0 && state.player.total && state.player.total > 0) {
381
257
  return DurationHelper.formatDuration(
382
258
  Math.round(state.player.elapsed * state.player.total)
383
259
  );
384
260
  }
385
261
  return '--:--';
386
262
  },
387
-
388
- percentProgress: (state:any) => {
263
+ percentProgress: (state: StoreState) => {
264
+ if(!state.player.elapsed){return 0;}
389
265
  return state.player.elapsed * 100;
390
266
  },
391
-
392
- totalTime: (state:any) => {
393
- if (state.player.elapsed > 0 && state.player.total > 0)
267
+ totalTime: (state: StoreState) => {
268
+ if (state.player.elapsed && state.player.elapsed > 0 && state.player.total && state.player.total > 0)
394
269
  return DurationHelper.formatDuration(Math.round(state.player.total));
395
270
  return '--:--';
396
271
  },
397
- totalSecondes: (state:any) => state.player.total,
272
+ totalSecondes: (state: StoreState) => state.player.total,
398
273
  }),
399
-
400
- audioUrl():any {
274
+ audioUrl(): string {
401
275
  if (this.media) return this.media.audioUrl;
402
276
  if (!this.podcast) return '';
403
277
  if (!this.podcast.availability.visibility)
404
278
  return this.podcast.audioStorageUrl;
405
279
  if (this.listenError) return this.podcast.audioStorageUrl;
406
- let parameters = [];
280
+ const parameters = [];
407
281
  parameters.push('origin=octopus');
408
282
  parameters.push('cookieName=player_' + this.podcast.podcastId);
283
+ parameters.push('listenerId='+this.getListenerId());
409
284
  if (
410
285
  this.$store.state.authentication &&
411
286
  this.$store.state.authentication.organisationId
@@ -416,8 +291,7 @@ export default defineComponent({
416
291
  }
417
292
  return this.podcast.audioUrl + '?' + parameters.join('&');
418
293
  },
419
-
420
- podcastShareUrl():any {
294
+ podcastShareUrl(): any {
421
295
  if (this.podcast) {
422
296
  return {
423
297
  name: 'podcast',
@@ -427,8 +301,7 @@ export default defineComponent({
427
301
  }
428
302
  return '';
429
303
  },
430
-
431
- podcastTitle():string {
304
+ podcastTitle(): string {
432
305
  if (this.podcast) {
433
306
  if (this.isEmissionName)
434
307
  return this.emissionName + ' - ' + this.podcast.title;
@@ -442,23 +315,84 @@ export default defineComponent({
442
315
  }
443
316
  return '';
444
317
  },
445
-
446
- emissionName():string {
318
+ emissionName(): string {
447
319
  if (this.podcast) return this.podcast.emission.name;
448
320
  return '';
449
321
  },
450
-
451
- organisationId() {
322
+ organisationId(): string {
452
323
  return state.generalParameters.organisationId;
453
324
  },
454
325
  },
455
326
 
327
+ watch: {
328
+ async live(): Promise<void> {
329
+ this.hlsReady = false;
330
+ this.setDownloadId(null);
331
+ this.listenError = false;
332
+ await this.playLive();
333
+ this.initComments();
334
+ },
335
+ playerHeight(): void {
336
+ this.$emit('hide', 0 === this.playerHeight ? true : false);
337
+ },
338
+ podcast(): void {
339
+ this.setDownloadId(null);
340
+ this.listenError = false;
341
+ this.initComments();
342
+ },
343
+ async listenTime(newVal): Promise<void> {
344
+ if (!this.podcast && !this.live) {
345
+ //Nothing can be done there is no listen time
346
+ return;
347
+ }
348
+ if (!this.getDownloadId()) {
349
+ //nothing can be done there is no downloadId
350
+ return;
351
+ }
352
+ if (newVal - this.lastSend < 10) {
353
+ //Last send is too recent, do nothing
354
+ return;
355
+ }
356
+ this.lastSend = newVal;
357
+ await octopusApi.updatePlayerTime(
358
+ this.getDownloadId(),
359
+ Math.round(newVal)
360
+ );
361
+ },
362
+ commentsLoaded(): void {
363
+ this.initComments(true);
364
+ },
365
+ },
366
+
367
+ mounted() {
368
+ moment.locale('fr');
369
+ if (this.isClock) {
370
+ setInterval(() => {
371
+ this.actualTime = moment(new Date()).format('HH:mm:ss');
372
+ }, 1000);
373
+ }
374
+ window.addEventListener('beforeunload', this.endListeningProgress);
375
+ this.watchPlayerStatus();
376
+ },
377
+
456
378
  methods: {
457
- watchPlayerStatus() {
379
+ getListenerId(): string{
380
+ let listenerId = this.getCookie("octopus_listenerId");
381
+ if(!listenerId){
382
+ listenerId = new Date().valueOf().toString() + Math.random();
383
+ let domain: any = /\.(.+)/.exec(window.location.host);
384
+ if(/\.(.+)/.exec(window.location.host)){
385
+ domain = domain[1];
386
+ }
387
+ this.setCookie("octopus_listenerId", listenerId, ';domain='+domain);
388
+ }
389
+ return listenerId;
390
+ },
391
+ watchPlayerStatus(): void {
458
392
  this.$store.watch(
459
- (state:any) => state.player.status,
460
- (newValue:any) => {
461
- const audioPlayer:any = document.querySelector('#audio-player');
393
+ (state: StoreState) => state.player.status,
394
+ (newValue: string) => {
395
+ const audioPlayer: any = document.querySelector('#audio-player');
462
396
  if (!audioPlayer) return;
463
397
  if (this.live && !this.hlsReady) {
464
398
  audioPlayer.pause();
@@ -474,57 +408,45 @@ export default defineComponent({
474
408
  }
475
409
  );
476
410
  },
477
- getDownloadId() {
478
- //TODO
479
- return undefined;
480
- /* return this._downloadId; */
411
+ getDownloadId(): any {
412
+ return this.downloadId;
481
413
  },
482
-
483
- setDownloadId(newValue?: any) {
414
+ setDownloadId(newValue?: any): void {
484
415
  this.endListeningProgress();
485
- //TODO
486
- console.log(newValue);
487
- /* this._downloadId = newValue; */
416
+ this.downloadId = newValue;
488
417
  },
489
-
490
- onError() {
418
+ onError(): void {
491
419
  if (this.podcast && !this.listenError) {
492
420
  this.listenError = true;
493
421
  } else if (this.podcast || this.media) {
494
422
  this.playerError = true;
495
423
  }
496
424
  },
497
-
498
- switchPausePlay() {
499
- const audioPlayer:any = document.querySelector('#audio-player');
425
+ switchPausePlay(): void {
426
+ const audioPlayer: any = document.querySelector('#audio-player');
500
427
  if (audioPlayer.paused) {
501
428
  this.onPlay();
502
429
  } else {
503
430
  this.onPause();
504
431
  }
505
432
  },
506
-
507
- stopPlayer() {
433
+ stopPlayer(): void {
508
434
  this.$store.commit('playerPlayPodcast');
509
435
  },
510
-
511
- seekTo(event: { currentTarget: { getBoundingClientRect: () => any; clientWidth: any; }; clientX: number; }) {
512
- const audioPlayer:any = document.querySelector('#audio-player');
436
+ seekTo(event: { currentTarget: { getBoundingClientRect: () => any; clientWidth: any }; clientX: number }): void {
437
+ const audioPlayer: any = document.querySelector('#audio-player');
513
438
  const rect = event.currentTarget.getBoundingClientRect();
514
439
  const barWidth = event.currentTarget.clientWidth;
515
440
  const x = event.clientX - rect.left; //x position within the element.
516
-
517
441
  const percentPosition = x / barWidth;
518
442
  if (percentPosition * 100 >= this.percentLiveProgress) return;
519
-
520
- const seekTime = this.$store.state.player.total! * percentPosition;
443
+ const seekTime = this.$store.state.player.total * percentPosition;
521
444
  if (this.podcast || this.live) {
522
445
  this.notListenTime = seekTime - this.listenTime;
523
446
  }
524
447
  audioPlayer.currentTime = seekTime;
525
448
  },
526
-
527
- onTimeUpdate(event: { currentTarget: { currentTime: number; duration: any; }; }) {
449
+ onTimeUpdate(event: { currentTarget: { currentTime: number; duration: any } }): void {
528
450
  if (this.podcast || this.live) {
529
451
  if (!this.getDownloadId()) {
530
452
  this.loadDownloadId();
@@ -543,10 +465,8 @@ export default defineComponent({
543
465
  }
544
466
  const streamDuration = event.currentTarget.duration;
545
467
  if (!streamDuration) return;
546
-
547
468
  const playerCurrentTime = event.currentTarget.currentTime;
548
469
  if (!playerCurrentTime) return;
549
-
550
470
  if (!this.live) {
551
471
  this.displayAlertBar = false;
552
472
  this.percentLiveProgress = 100;
@@ -554,7 +474,6 @@ export default defineComponent({
554
474
  this.$store.commit('playerElapsed', playerCurrentTime / streamDuration);
555
475
  return;
556
476
  }
557
-
558
477
  const scheduledDuration = this.live.duration / 1000;
559
478
  if (scheduledDuration > streamDuration) {
560
479
  this.displayAlertBar = false;
@@ -572,32 +491,27 @@ export default defineComponent({
572
491
  this.$store.commit('playerElapsed', playerCurrentTime / streamDuration);
573
492
  }
574
493
  },
575
-
576
- onPlay() {
494
+ onPlay(): void {
577
495
  this.$store.commit('playerPause', false);
578
496
  },
579
-
580
- onPause() {
497
+ onPause(): void {
581
498
  this.$store.commit('playerPause', true);
582
499
  },
583
-
584
- onFinished() {
500
+ onFinished(): void {
585
501
  this.setDownloadId(null);
586
502
  if (this.live) {
587
- let audio:any = document.getElementById('audio-player');
503
+ const audio: any = document.getElementById('audio-player');
588
504
  audio.src = '';
589
505
  }
590
506
  this.forceHide = true;
591
507
  },
592
-
593
- onHidden() {
508
+ onHidden(): void {
594
509
  if (this.forceHide) {
595
510
  this.$store.commit('playerPlayPodcast');
596
511
  this.forceHide = false;
597
512
  }
598
513
  },
599
-
600
- loadDownloadId() {
514
+ loadDownloadId(): void {
601
515
  if (!this.podcast) return;
602
516
  const matching_cookies = document.cookie
603
517
  .split(';')
@@ -606,14 +520,14 @@ export default defineComponent({
606
520
  return _return.map(item => item.trim());
607
521
  })
608
522
  .filter(item => {
523
+ if(!this.podcast){return '';}
609
524
  return 'player_' + this.podcast.podcastId === item[0];
610
525
  });
611
526
  if (1 === matching_cookies.length) {
612
527
  this.setDownloadId(matching_cookies[0][1]);
613
528
  }
614
529
  },
615
-
616
- async endListeningProgress() {
530
+ async endListeningProgress(): Promise<void> {
617
531
  if (!this.getDownloadId()) return;
618
532
  await octopusApi.updatePlayerTime(
619
533
  this.getDownloadId(),
@@ -624,13 +538,21 @@ export default defineComponent({
624
538
  this.lastSend = 0;
625
539
  this.listenTime = 0;
626
540
  },
627
-
628
- async initHls(hlsStreamUrl: string) {
629
- return new Promise<void>((resolve, reject) => {
541
+ async initHls(hlsStreamUrl: string): Promise<void> {
542
+ return new Promise<void>(async(resolve, reject) => {
543
+ if(null === Hls){
544
+ //TODO -> Version light min quand ce sera possible
545
+ await import('hls.js/dist/hls.js').then((hlsLibrary) => {
546
+ Hls = hlsLibrary.default;
547
+ })
548
+ await import('hls.js').then((hlsLibrary) => {
549
+ Hls = hlsLibrary.default;
550
+ })
551
+ }
630
552
  if (!Hls.isSupported()) {
631
553
  reject('Hls is not supported ! ');
632
554
  }
633
- var hls = new Hls();
555
+ const hls = new Hls();
634
556
  hls.on(Hls.Events.MANIFEST_PARSED, async () => {
635
557
  let downloadId = null;
636
558
  try {
@@ -648,7 +570,7 @@ export default defineComponent({
648
570
  console.log('ERROR downloadId');
649
571
  }
650
572
  this.hlsReady = true;
651
- let audio:any = document.getElementById('audio-player');
573
+ const audio: any = document.getElementById('audio-player');
652
574
  hls.attachMedia(audio);
653
575
  await audio.play();
654
576
  this.onPlay();
@@ -660,10 +582,9 @@ export default defineComponent({
660
582
  hls.loadSource(hlsStreamUrl);
661
583
  });
662
584
  },
663
-
664
- async playLive() {
585
+ async playLive(): Promise<void> {
665
586
  if (!this.live) return;
666
- let hlsStreamUrl =
587
+ const hlsStreamUrl =
667
588
  state.podcastPage.hlsUri +
668
589
  'stream/dev.' +
669
590
  this.live.conferenceId +
@@ -677,8 +598,7 @@ export default defineComponent({
677
598
  }, 1000);
678
599
  }
679
600
  },
680
-
681
- editRight(organisation: any) {
601
+ editRight(organisation: any): boolean {
682
602
  if (
683
603
  (state.generalParameters.isCommments &&
684
604
  this.organisationId === organisation) ||
@@ -687,8 +607,7 @@ export default defineComponent({
687
607
  return true;
688
608
  return false;
689
609
  },
690
-
691
- async initComments(refresh = false) {
610
+ async initComments(refresh = false): Promise<void> {
692
611
  let podcastId, organisation;
693
612
  if (this.podcast) {
694
613
  podcastId = this.podcast.podcastId;
@@ -706,7 +625,7 @@ export default defineComponent({
706
625
  }
707
626
  let first = 0;
708
627
  let count = 0;
709
- let size = 50;
628
+ const size = 50;
710
629
  if (
711
630
  podcastId &&
712
631
  this.$store.state.comments.actualPodcastId === podcastId
@@ -727,66 +646,151 @@ export default defineComponent({
727
646
  )
728
647
  return;
729
648
  while (0 === first || this.comments.length < count) {
730
- let param:any = {
649
+ const param: any = {
731
650
  first: first,
732
651
  size: size,
733
652
  podcastId: podcastId,
734
653
  };
735
654
  if (!this.editRight(organisation)) {
736
- param.status = 'Valid';
655
+ param.status = ['Valid'];
737
656
  }
738
657
  const data = await octopusApi.fetchRootComments(param);
739
658
  first += size;
740
659
  count = data.totalElements;
741
- this.comments = this.comments.concat(data.content).filter((c: null) => {
660
+ this.comments = this.comments.concat(data.content).filter((c: CommentPodcast) => {
742
661
  return null !== c;
743
662
  });
744
663
  }
745
664
  },
746
665
  },
666
+ })
667
+ </script>
747
668
 
748
- watch: {
749
- async live() {
750
- this.hlsReady = false;
751
- this.setDownloadId(null);
752
- this.listenError = false;
753
- await this.playLive();
754
- this.initComments();
755
- },
669
+ <style lang="scss">
670
+ @import '../../sass/_variables.scss';
756
671
 
757
- playerHeight(newVal) {
758
- this.$emit('hide', 0 === newVal ? true : false);
759
- },
672
+ .play-button-box {
673
+ height: 2.5rem;
674
+ width: 2.5rem;
675
+ display: flex;
676
+ align-items: center;
677
+ justify-content: center;
678
+ margin: 0 0.5rem;
679
+ border-radius: 50%;
680
+ font-size: 1.2rem;
681
+ flex-shrink: 0;
682
+ cursor: pointer;
683
+ }
760
684
 
761
- podcast() {
762
- this.setDownloadId(null);
763
- this.listenError = false;
764
- this.initComments();
765
- },
685
+ .player-container {
686
+ position: fixed;
687
+ overflow: hidden;
688
+ z-index: 12;
689
+ width: 100%;
690
+ bottom: 0;
691
+ display: flex;
692
+ flex-direction: column;
693
+ transition: height 1s;
694
+ background: #282828 !important;
695
+ max-width: 100%;
696
+ font-size: 1rem;
766
697
 
767
- async listenTime(newVal) {
768
- if (!this.podcast && !this.live) {
769
- //Nothing can be done there is no listen time
770
- return;
771
- }
772
- if (!this.getDownloadId()) {
773
- //nothing can be done there is no downloadId
774
- return;
775
- }
776
- if (newVal - this.lastSend < 10) {
777
- //Last send is too recent, do nothing
778
- return;
779
- }
780
- this.lastSend = newVal;
781
- await octopusApi.updatePlayerTime(
782
- this.getDownloadId(),
783
- Math.round(newVal)
784
- );
785
- },
698
+ .player-image {
699
+ border-radius: 0.2rem;
700
+ height: 2.4rem;
701
+ width: 2.4rem;
702
+ }
703
+ .player-progress-border {
704
+ height: 10px;
705
+ width: 3px;
706
+ background: black;
707
+ }
708
+ .progress {
709
+ align-items: flex-end;
710
+ height: 10px;
711
+ position: relative;
712
+ }
713
+ .progress-bar-duration {
714
+ width: 10px;
715
+ }
716
+ .progress-bar {
717
+ height: 4px;
718
+ position: absolute;
719
+ }
786
720
 
787
- commentsLoaded() {
788
- this.initComments(true);
789
- },
790
- },
791
- });
792
- </script>
721
+ .progress.custom-bg-darkgrey {
722
+ background: #555;
723
+ }
724
+
725
+ .progress-bar.custom-bg-grey {
726
+ background: #e9ecef;
727
+ }
728
+
729
+ .player-title,
730
+ .hide-phone {
731
+ font-size: 0.8rem;
732
+ margin: 0 0 5px 0;
733
+ }
734
+ .player-grow-content {
735
+ display: flex;
736
+ flex-grow: 1;
737
+ flex-direction: column;
738
+ flex-shrink: 1;
739
+ flex-basis: 20px;
740
+ overflow: hidden;
741
+ }
742
+ .player-title {
743
+ font-size: 0.8rem;
744
+ margin: 0 0 5px 0;
745
+ }
746
+
747
+ .hide-phone {
748
+ font-size: 0.8rem;
749
+ margin: 0 0 5px 0;
750
+ }
751
+ .timeline-button {
752
+ background: black;
753
+ padding: 0.1rem;
754
+ border-radius: 50%;
755
+ width: 70px;
756
+ height: 70px;
757
+ font-size: 0.7rem;
758
+ font-weight: bold;
759
+ justify-content: center;
760
+ display: flex;
761
+ flex-direction: column;
762
+ align-items: center;
763
+ cursor: pointer;
764
+ color: $octopus-primary-color;
765
+ margin-left: 0.5rem;
766
+ @media (max-width: 960px) {
767
+ display: none;
768
+ }
769
+ }
770
+ }
771
+ /** PHONES*/
772
+ @media (max-width: 450px) {
773
+ .player-container {
774
+ .player-image {
775
+ height: 2rem;
776
+ width: 2rem;
777
+ }
778
+ }
779
+ }
780
+
781
+ @media (max-width: 960px) {
782
+ .player-container {
783
+ .d-flex {
784
+ @media (max-width: 960px) {
785
+ flex-wrap: nowrap !important;
786
+ }
787
+ }
788
+ .player-title {
789
+ font-size: 12px;
790
+ overflow: hidden;
791
+ white-space: nowrap;
792
+ text-overflow: ellipsis;
793
+ }
794
+ }
795
+ }
796
+ </style>