1Vue.filter('dotted', function (value) 2{ 3 var numberAsText = '' + value; 4 var number = parseInt(value); 5 var dots = Math.floor((numberAsText.length - 1) / 3); 6 var dotted = "" 7 for (var i = 1; i <= dots; i++) 8 { 9 dotted = '.' + numberAsText.substr(-3 * i, 3) + dotted; 10 } 11 dotted = numberAsText.substr(0, numberAsText.length - 3 * dots) + dotted; 12 return dotted 13}); 14 15 16var vueLanguageMainMenu = new Vue({ 17 el: '#vue-language-mainmenu', 18 data: { 19 showLangMenu: false, 20 /* Trend menu refactor Start*/ 21 vm: { 22 trends: [], 23 loading: false, 24 ready: false, 25 trendFinish: true, 26 count: 5, 27 loadCount: 8, 28 maxcount: 41, 29 visibleTrends: true, 30 isTrendMenu: false, 31 runs:true, 32 webpLength: 3000, 33 timeout: null, 34 noWebpSupport: false 35 }, 36 broadcastformatlist: [], 37 38 /* Trend menu refactor END*/ 39 40 // Shorts-Menue (#973): wird erst beim ersten Ueberfahren des Menuepunkts geladen 41 menuShorts: [], 42 menuShortsRequested: false 43 }, 44 mounted: function(){ 45 this.doInitialRequest(0); 46 this.loadBroadcastFormats(); 47 // No WebP Support at Safari 3.0+ and Internet Explorer 6-11 48 this.vm.noWebpSupport = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification)) || /*@cc_on!@*/false || !!document.documentMode; 49 50 }, 51 computed: { 52 emptySendereihenElements: function(){ 53 var fakeElements = []; 54 if(this.broadcastformatlist.length % 4 != 0){ 55 var len = this.broadcastformatlist.length 56 var rest = len-parseInt(len/4)*4 57 for(var i=0; i<4-rest; i++){ 58 fakeElements.push(i) 59 } 60 } 61 62 return fakeElements 63 } 64 }, 65 methods: { 66 loadBroadcastFormats: function () { //init process 67 var self = this; 68 self.lang = this.$refs.menuBroadcast.dataset.lang; 69 axios.get(vueConfig('api') + 'hashtags?all_results=1&type=broadcastformat&lang='+self.lang, vueConfig('authorization')) 70 .then(function (response) { 71 self.broadcastformatlist = response.data; 72 }); 73 }, 74 encode: function(val){ 75 return window.encodeURIComponent(val) 76 }, 77 loadMenuShorts: function (lang) { 78 var self = this; 79 if (self.menuShortsRequested) { 80 // schon geladen: Slick nur neu ausrichten, falls es beim ersten Mal unsichtbar initialisiert wurde 81 if ($('.menu-shorts-slider').hasClass('slick-initialized')) { 82 $('.menu-shorts-slider').slick('setPosition'); 83 } 84 return; 85 } 86 self.menuShortsRequested = true; 87 axios.get(vueConfig('api') + 'shorts/initial?locale=' + self.encode(lang) + '&limit=18', vueConfig('authorization')) 88 .then(function (response) { 89 self.menuShorts = response.data; 90 self.$nextTick(function () { 91 $('.menu-shorts-slider').slick({ 92 dots: false, 93 infinite: false, 94 lazyLoad: 'ondemand', 95 slidesToShow: 6, 96 slidesToScroll: 6 97 }); 98 }); 99 }) 100 .catch(function (e) { 101 console.log("[MenuShorts]: " + e); 102 self.menuShorts = []; 103 self.menuShortsRequested = false; 104 }); 105 }, 106 doInitialRequest: function (initLoad) 107 { 108 109 var self = this; 110 var url = window.location.origin + window.location.pathname 111 axios.post(url,{ 112 data: { 113 type: 'loadingTrends', 114 offset: 0, 115 count: self.vm.count + initLoad 116 }}) 117 .then(function (response){ 118 self.vm.trends = response.data.data; 119 self.vm.loading = true; 120 self.vm.ready = true; 121 if (self.vm.trends.length == 0) 122 { 123 self.vm.visibleTrends = false;
124 } 125 }) 126 .catch(function(e){ 127 console.log("[TrendLazyLoader]: " + e) 128 self.vm.trends = []; 129 self.vm.visibleTrends = false; 130 }) 131 }, 132 133 134 textWithDots: function (text) 135 { 136 text = '' + text 137 var dots = (text.length > 70) ? "..." : ""; 138 var cuttedText = "" 139 text.split(" ").forEach(element => 140 { 141 if (cuttedText.length + element.length + 1 <= 70) 142 { 143 cuttedText = cuttedText + element + " " 144 } 145 }); 146 147 return cuttedText + dots 148 }, 149 150 ktv_link_to_youtube_or_website: function(videoObj){ 151 if (!videoObj) 152 { 153 return ""; 154 } 155 156 // #47 only show DE YT after 2020 157 if (videoObj.datum >= '2021-01-01' && videoObj.youtube_link.length >= 11) 158 { 159 return "https://youtu.be/" + videoObj.youtube_link; 160 } else 161 { 162 return "https://www.kla.tv/" + videoObj.id; 163 } 164 }, 165 rawurlencode: function(link){ 166 // If some strange undefined is as input given 167 link = (link + '') 168 return window.encodeURIComponent(link) 169 .replace(/!/g, '%21') 170 .replace(/'/g, '%27') 171 .replace(/\(/g, '%28') 172 .replace(/\)/g, '%29') 173 .replace(/\*/g, '%2A'); 174 175 }, 176 toggleLangMenu: function(){ 177 this.showLangMenu = !this.showLangMenu; 178 }, 179 180 preview_hover: function(id){ 181 // register and run (because the "this" context is only inside this function correct) 182 shareVueAngularFunction.registerBroadcastImageHoverIn(this.vm)(id) 183 }, 184 185 preview_leave: function(id){ 186 // register and run (because the "this" context is only inside this function correct) 187 shareVueAngularFunction.registerBroadcastImageHoverOut(this.vm)(id) 188 }, 189 truncateText(text, maxLength) { 190 if (!text) return ''; 191 192 if (text.length <= maxLength) { 193 return text; 194 } 195 196 // Bei maxLength abschneiden 197 let truncated = text.substring(0, maxLength); 198 199 // Bis zum letzten vollständigen Wort zurückgehen 200 truncated = truncated.substring(0, truncated.lastIndexOf(' ')); 201 202 return truncated + ' ...'; 203 } 204 } 205}) 206 207 208Vue.component("language-menu-main", { 209 template: `<div class=""> 210 211<!-- Modal --> 212<div id="vueLanguageMainModel" style="z-index: 100000; margin-top: 5vh;" class="modal fade" role="dialog"> 213 <div class="modal-dialog modal-lg"> 214 215 <!-- Modal content--> 216 <div class="modal-content"> 217 <div class="modal-body"> 218 219 <div id="vueLanguageModelContainer"> 220 221 <span id="vueLanguageModelHeadline">{{'Wählen Sie Ihre Sprache aus'}} <span style="font-size: 1.2rem;">({{'Insgesamt'}} {{langCount | dotted}} {{'Sprachen'}})</span></span> 222 <span @click="close()" class="langMainMenuLangClose">X</span> 223 </div> 224 <div id="vueLanguageModelFlaggContainer"> 225 <h4 style="margin-left: 11px;margin-top: 10px;">Sprache</h4> 226 <div class="actionBar langMainMenuLangItemM10" style="text-align: left; margin-top: 10px;"> 227 <input class="form-control" style="height: 40px;" placeholder="Eine Sprache eingeben oder anklicken" v-model="langSearch" /> 228 </div> 229 230 <div class="mainContainer langMainMenuLangItemM10" style="border: 1px solid grey; margin-top: 10px; overflow-y: scroll;max-height: 590px;"> 231 232 <div class="selectedLang langMainMenuLangItemSelected" style="width: 100%;height: 58px;"> 233 <language-menu-language-item :rootslash="rootslash" :lang="selectedLanguage"></language-menu-language-item> 234 235 <hr> 236 </div> 237 238 <div class="allLangContainer container"> 239 <div class="row"> 240 241 <language-menu-language-item :rootslash="rootslash" class="col-4 col" v-for="lang in languagesFiltered" :lang="lang"></language-menu-language-item> 242 243 </div> 244 </div> 245 246 </div> 247 248 249 </div> 250 251 252 253 254 </div> 255 256 257 </div> 258 259 </div> 260</div> 261 262 263 264 265 266 </div> 267 `, 268 props: ['rootslash', 'display', 'lang', 'onmountdisplay'], 269 data: function () 270 { 271 return { 272 languages: [], 273 loading: true, 274 langSearch: '', 275 }; 276 }, 277 mounted: function () 278 { 279 this.loadLanguages() 280 if(this.onmountdisplay){ 281 $("#vueLanguageMainModel").modal() 282 } 283 284 }, 285 methods: { 286 fixLangFlaggIfNotExist: function(){ 287 for(let langkey in this.languages){ 288 let _self = this; 289 let orgimg = this.languages[langkey]['img'] 290 291 axios(orgimg) 292 .then(function(data){}) 293 .catch(function(error){ 294 if (orgimg == undefined) return; 295 296 let oldElems = orgimg.split('/') 297 let langKu = oldElems[oldElems.length - 1].replace('.png', '') 298 299 let langObj = _self.languages.filter(function(lang){ 300 return lang['langku'] == langKu 301 })[0] 302 303 let langkey = _self.languages.indexOf(langObj) 304 oldElems[oldElems.length - 1] = 'missing_flag.png' 305 _self.languages[langkey]['img'] = oldElems.join('/') 306 }) 307 } 308 }, 309 310 loadLanguages: function(){ 311 var _self = this; 312 axios.get(vueConfig('api') + 'languages?translated=true', vueConfig('authorization')) 313 .then(function (response){ 314 _self.languages = response.data.map(function(v){ 315 return { 'name': v.langdesc, 'img': _self.rootslash + 'images/glob_language_bigger/24x24/' + v.langku + '.png', 'langku': v.langku, 'shortname': v.langku, 'translated': v.name, 'catid': v.catid, 'videos': v.videos } 316 }) 317 }).catch(function(e){ 318 319 }).then(_self.fixLangFlaggIfNotExist) 320 }, 321 322 close: function () 323 { 324 //$("#vueLanguageMainModel").modal('toggle') 325 $("#vueLanguageMainModel").modal('hide') 326 } 327 }, 328 watch: { 329 display: function(){ 330 $("#vueLanguageMainModel").modal('toggle') 331 } 332 }, 333 computed: { 334 selectedLanguage: function(){ 335 if (this.languages.length == 0) return [] 336 var self = this 337 return this.languages.filter(function(v){ 338 return v.shortname == self.lang 339 })[0] 340 }, 341 342 343 languagesFiltered: function () 344 { 345 var filterLangs = this.langSearch.toLowerCase() 346 return this.languages.filter(function (v) 347 { 348 return (v['name'].toLowerCase().indexOf(filterLangs) >= 0 || v['shortname'].toLowerCase().indexOf(filterLangs) >= 0 349 || v['translated'].toLowerCase().indexOf(filterLangs) >= 0) && v['langku'].length > 0 350 }); 351 }, 352 langCount: function () 353 { 354 return this.languages.length 355 } 356 } 357}); 358 359 360 361 362Vue.component("language-menu-language-item", { 363 template: `<div @click="navigateLanguage()" class="langMainMenuLangItemContainer" style=" "> 364 <div class="container"> 365 <div class="row flex-nowrap"> 366 <div class="column imageContainer"> 367 <img src="/images/_global/ktv-logo-blank-blue.svg" /> 368 <div class="langShort" v-html="lang.langku"></div> 369 </div> 370 <div class="column descContainer" style="line-height: 1.4;"> 371 <div style="color: grey;">
372 <span v-if="lang.catid > 0" v-html="lang.translated"></span> 373 <span v-else v-html="lang.name"></span> 374 375 </div> 376 <div style="color: black;font-size: 15px;" v-html="lang.name"></div> 377 <!--<span>({{lang.videos | dotted}})</span>--> 378 </div> 379 </div> 380 </div> 381 382 </div> 383 `, 384 props: ['lang', 'rootslash'], 385 data: function () 386 { 387 return { 388 389 }; 390 }, 391 mounted: function () 392 { 393 394 }, 395 methods: { 396 navigateLanguage: function() { 397 let url = new URL(location.href); 398 if(url.search != null && url.search.startsWith("?a=showdownloadcenter") || url.pathname != null && url.pathname.startsWith("/sichern")) { 399 url.searchParams.set('lang', this.lang.shortname); 400 location.href = url.href; 401 } else { 402 location.href = `${this.rootslash}${this.lang.shortname}`; 403 } 404 } 405 } 406});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.