<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Multiwatch</title> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <style type="text/css"> body { max-width: 600px; margin: auto; text-align: center; font-family: sans-serif; } h1 a { text-decoration: none; color: black; } .flex { display: flex; flex-wrap: wrap; } .flex div { width: 200px; text-align: left; } .left { text-align: left; } .error { color: red; font-weight: bold; } .pointer { cursor: pointer; } .poster { height: 392px; width: 276px; display: inline-block; background-color: gray; margin: 1em; } .no-bullet { list-style-type: none; } </style> </head> <body> <div id="app"> <h1><a href="./index.html">Multiwatch</a></h1> <p v-if="step > 1"><a href="./index.html">Back</a></p> <p v-if="error" class="error">{{ error }}</p> <div v-if="step == 1"> <h2>Search</h2> <form id="searchForm" v-on:submit.prevent="search"> <p> <label for="title">Title:</label> <input type="text" v-model="title" id="title" /> </p> <h3>Countries</h3> <div class="flex"> <div v-for="(localeId, country) in availableCountries"> <input type="checkbox" v-bind:id="localeId" v-bind:checked="checkedLocales.indexOf(localeId) !== -1" v-on:click="() => toggleCheckbox(localeId)"> <label v-bind:for="localeId">{{ country }}</label> </div> </div> <p> <input type="submit" value="Search"/> </p> </form> </div> <div v-else> <ul v-if="step == 2" class="no-bullet"> <li v-for="(item, index) in searchItems"> <img class="pointer poster" v-bind:src="item.poster_url" v-bind:alt="item.title" v-on:click="() => loadItem(index)" /> </li> </ul> <div v-else> <div v-for="(localeOffers, locale) in offers"> <h3>{{ availableLocales[locale] }}</h3> <ul v-if="localeOffers.length > 0" class="left"> <li v-for="offer in localeOffers"><a v-bind:href="offer">{{ offer }}</a></li> </ul> <p v-else>None</p> </div> </div> </div> </div> <script type="text/javascript"> var JUSTWATCH_API_DOMAIN = 'https://apis.justwatch.com'; var checkedLocales = JSON.parse(localStorage.getItem('checkedLocales')); if (!checkedLocales) { checkedLocales = ['fr_FR', 'en_AU', 'en_CA', 'de_DE', 'pl_PL', 'en_SG', 'en_UK']; } var app = new Vue({ el: '#app', computed: { availableLocales() { var out = {}; Object.keys(this.availableCountries).forEach((country) => { out[this.availableCountries[country]] = country; }); return out; }, }, data: { checkedLocales: checkedLocales, availableCountries: { "Afghanistan": "ps_AF", "Albania": "sq_AL", "Algeria": "ar_DZ", "Andorra": "ca_AD", "Antigua And Barbuda": "en_AG", "Argentina": "es_AR", "Armenia": "hy_AM", "Aruba": "nl_AW", "Australia": "en_AU", "Austria": "de_AT", "Azerbaijan": "az_AZ", "Bahrain": "ar_BH", "Bangladesh": "bn_BD", "Belarus": "be_BY", "Belgium": "fr_BE", "Bhutan": "dz_BT", "Bolivia": "es_BO", "Bosnia And Herzegovina": "bs_BA", "Botswana": "en_BW", "Brazil": "pt_BR", "Bulgaria": "bg_BG", "Cambodia": "km_KH", "Canada": "en_CA", "Chile": "es_CL", "China": "zh_CN", "Colombia": "es_CO", "Costa Rica": "es_CR", "Croatia": "hr_HR", "Cyprus": "el_CY", "Czech Republic": "cs_CZ", "Denmark": "da_DK", "Djibouti": "so_DJ", "Dominican Republic": "es_DO", "Ecuador": "es_EC", "Egypt": "ar_EG", "El Salvador": "es_SV", "Eritrea": "tig_ER", "Estonia": "et_EE", "Ethiopia": "am_ET", "Faroe Islands": "fo_FO", "Finland": "fi_FI", "France": "fr_FR", "Georgia": "ka_GE", "Germany": "de_DE", "Greece": "el_GR", "Greenland": "kl_GL", "Guatemala": "es_GT", "Haiti": "ht_HT", "Honduras": "es_HN", "Hong Kong": "en_HK", "Hungary": "hu_HU", "Iceland": "is_IS", "India": "en_IN", "Indonesia": "id_ID", "Iran, Islamic Republic Of": "fa_IR", "Iraq": "ar_IQ", "Ireland": "en_IE", "Israel": "he_IL", "Italy": "it_IT", "Japan": "ja_JP", "Jordan": "ar_JO", "Kazakhstan": "kk_KZ", "Kenya": "om_KE", "Korea, Republic Of": "ko_KR", "Kuwait": "ar_KW", "Kyrgyzstan": "ky_KG", "Latvia": "lv_LV", "Lebanon": "ar_LB", "Libyan Arab Jamahiriya": "ar_LY", "Liechtenstein": "de_LI", "Lithuania": "lt_LT", "Luxembourg": "fr_LU", "Macedonia": "mk_MK", "Madagascar": "mg_MG", "Malaysia": "ms_MY", "Maldives": "dv_MV", "Malta": "mt_MT", "Mexico": "es_MX", "Mongolia": "mn_MN", "Morocco": "ar_MA", "Myanmar": "my_MM", "Nepal": "ne_NP", "Netherlands": "nl_NL", "Netherlands Antilles": "pap_AN", "New Zealand": "en_NZ", "Nicaragua": "es_NI", "Nigeria": "en_NG", "Norway": "no_NO", "Oman": "ar_OM", "Pakistan": "pa_PK", "Panama": "es_PA", "Paraguay": "es_PY", "Peru": "es_PE", "Philippines": "en_PH", "Poland": "pl_PL", "Portugal": "pt_PT", "Puerto Rico": "es_PR", "Qatar": "ar_QA", "Romania": "ro_RO", "Russian Federation": "ru_RU", "Rwanda": "rw_RW", "Saudi Arabia": "ar_SA", "Senegal": "wo_SN", "Serbia And Montenegro": "sr_CS", "Singapore": "en_SG", "Slovakia": "sk_SK", "Slovenia": "sl_SI", "Somalia": "so_SO", "South Africa": "af_ZA", "Spain": "es_ES", "Sri Lanka": "si_LK", "Sudan": "ar_SD", "Sweden": "sv_SE", "Switzerland": "fr_CH", "Syrian Arab Republic": "ar_SY", "Taiwan": "zh_TW", "Tajikistan": "tg_TJ", "Thailand": "th_TH", "Tunisia": "ar_TN", "Turkey": "tr_TR", "Turkmenistan": "tk_TM", "Uganda": "lg_UG", "Ukraine": "uk_UA", "United Arab Emirates": "ar_AE", "United Kingdom": "en_GB", "United States": "en_US", "Uruguay": "es_UY", "Uzbekistan": "uz_UZ", "Venezuela": "es_VE", "Viet Nam": "vi_VN", "Yemen": "ar_YE", "Zimbabwe": "en_ZW" }, error: null, title: '', searchItems: [], offers: {}, step: 1, }, methods: { search() { fetch(`${JUSTWATCH_API_DOMAIN}/content/titles/fr_FR/popular?language=fr&body={"page_size":20,"page":1,"query":"${this.title}","content_types":["show","movie"]}`) .then(response => response.json()) .then(response => { this.error = null; if (!response.items || response.items.length == 0) { this.error = 'Not found' return; } this.searchItems = response.items.map((item) => { var poster = null; if (item['poster']) { poster = item['poster'].replace('{profile}', 's276'); } return { id: item.id, title: item.title, type: item.object_type, poster_url: `https://images.justwatch.com${poster}` }; }); this.step += 1; }) .catch(exc => this.error = exc); }, toggleCheckbox(localeId) { if (this.checkedLocales.indexOf(localeId) !== -1) { var index = this.checkedLocales.indexOf(localeId); this.checkedLocales.splice(index, 1); } else { this.checkedLocales.push(localeId); } localStorage.setItem('checkedLocales', JSON.stringify(this.checkedLocales)); }, loadItem(index) { this.offers = {}; this.error = null; var promises = []; this.checkedLocales.forEach((locale) => { var searchItem = this.searchItems[index]; var url = `${JUSTWATCH_API_DOMAIN}/content/titles/${searchItem.type}/${searchItem.id}/locale/${locale}?language=fr` promises.push(fetch(url) .then(response => response.json()) .then(response => { if (!response.offers) { this.offers[locale] = []; return; } this.offers[locale] = response.offers .filter(item => item.monetization_type == 'flatrate') .map(item => item.urls.standard_web); this.offers[locale] = [...new Set(this.offers[locale])]; }) .catch(exc => this.error = exc) ); }) Promise.all(promises).then(() => this.step += 1); }, }, }); </script> </body> </html>