ui work, settings stuff, update player, ui fixes

This commit is contained in:
ThaUnknown 2021-08-24 13:36:55 +02:00
parent 1d5a1673a4
commit 477a88418c
13 changed files with 115 additions and 93 deletions

View file

@ -39,6 +39,17 @@ img {
width: 3rem
}
.mw-600 {
max-width: 60rem;
}
break {
flex-basis: 100%;
width: 0px;
height: 0px;
overflow: hidden;
}
.font-size-30 {
font-size: 3rem !important
}

View file

@ -13,7 +13,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<meta property="og:title" content="Miru">
<meta property="og:url" content="https://mirumoe.netlify.app/">
<meta property="og:url" content="">
<meta property="og:description" content="Miru - Torrent streaming made simple!">
<meta property="og:type" content="video.other">
<meta property="og:image" content="logo.png">
@ -851,12 +851,12 @@
</a>
</div>
<div class="h-full">
<div class="settingsTabTorrent d-none content flex-column">
<div class="settingsTabTorrent d-none content flex-row flex-wrap mw-600">
<div class="form-control-lg w-600 h-150 mb-10">
<h1 class="content-title font-size-22">
Tracker List
</h1>
<textarea class="form-control w-600 h-100" id="torrent10" value="">wss://tracker.openwebtorrent.com
<textarea class="form-control w-600 h-100" id="torrent10">wss://tracker.openwebtorrent.com
wss://spacetradersapi-chatbox.herokuapp.com:443/announce
wss://peertube.cpy.re:443/tracker/socket</textarea>
</div>
@ -871,7 +871,7 @@ wss://peertube.cpy.re:443/tracker/socket</textarea>
<div class="input-group w-300 mb-10 form-control-lg" data-toggle="tooltip" data-placement="top"
data-title="Download/Upload Speed Limit For Torrents, Higher Values Increase CPU Usage">
<div class="input-group-prepend">
<span class="input-group-text">Speed Cap</span>
<span class="input-group-text w-150 justify-content-center">Max Speed</span>
</div>
<input id="torrent7" type="number" value="10" min="0" max="50"
class="form-control text-right form-control-lg">
@ -879,6 +879,7 @@ wss://peertube.cpy.re:443/tracker/socket</textarea>
<span class="input-group-text">MB/s</span>
</div>
</div>
<break></break>
<div class="custom-switch mb-10 pl-10 font-size-16 w-300" data-toggle="tooltip" data-placement="top"
data-title="Only Downloads Pieces Directly Required For Playback Instead Of The Entire File. Recommended Only For Low-End Devices">
<input type="checkbox" id="torrent8">
@ -886,11 +887,11 @@ wss://peertube.cpy.re:443/tracker/socket</textarea>
</div>
</div>
<div class="settingsTabPlayer d-none content flex-column">
<div class="settingsTabPlayer d-none content flex-row flex-wrap mw-600">
<div class="input-group mb-10 w-600 form-control-lg" data-toggle="tooltip" data-placement="top"
data-title="The Default Styles For Subtitles That Don't Have Styles Specified">
<div class="input-group-prepend">
<span class="input-group-text">Default Style</span>
<span class="input-group-text w-150 justify-content-center">Default Style</span>
</div>
<input id="subtitle1" type="text" list="subtitle1list" class="form-control form-control-lg"
autocomplete="off" value="SubsPlease">
@ -906,23 +907,23 @@ wss://peertube.cpy.re:443/tracker/socket</textarea>
<div class="input-group w-300 mb-10 form-control-lg" data-toggle="tooltip" data-placement="top"
data-title="Time For Player Controls To Hide">
<div class="input-group-prepend">
<span class="input-group-text">Immerse After</span>
<span class="input-group-text w-150 justify-content-center">Immerse Time</span>
</div>
<input id="player2" type="number" value="3" min="1" max="30"
class="form-control text-right form-control-lg">
<div class="input-group-append">
<span class="input-group-text">sec</span>
<span class="input-group-text w-50 justify-content-center">sec</span>
</div>
</div>
<div class="input-group w-300 mb-10 form-control-lg" data-toggle="tooltip" data-placement="top"
data-title="How Much To Seek Video">
<div class="input-group-prepend">
<span class="input-group-text">Seek</span>
<span class="input-group-text w-150 justify-content-center">Seek Time</span>
</div>
<input id="player3" type="number" value="2" min="1" max="30"
class="form-control text-right form-control-lg">
<div class="input-group-append">
<span class="input-group-text">sec</span>
<span class="input-group-text w-50 justify-content-center">sec</span>
</div>
</div>
<div class="custom-switch mb-10 pl-10 font-size-16 w-300" data-toggle="tooltip" data-placement="top"
@ -951,11 +952,11 @@ wss://peertube.cpy.re:443/tracker/socket</textarea>
<label for="other2">Autocomplete Episodes</label>
</div>
</div>
<div class="settingsTabRSS d-none content flex-column">
<div class="settingsTabRSS d-none content flex-row flex-wrap mw-600">
<div class="input-group mb-10 w-600 form-control-lg" data-toggle="tooltip" data-placement="top"
data-title="What RSS Feed To Fetch Releases From, Allows For Custom CORS Enabled Feeds">
<div class="input-group-prepend">
<span class="input-group-text">Feed</span>
<span class="input-group-text w-100 justify-content-center">Feed</span>
</div>
<input id="torrent4" type="text" list="torrent4list" class="form-control form-control-lg"
autocomplete="off" value="SubsPlease">
@ -967,7 +968,7 @@ wss://peertube.cpy.re:443/tracker/socket</textarea>
<div class="input-group mb-10 w-300 form-control-lg" data-toggle="tooltip" data-placement="top"
data-title="What Quality To Find Torrents In">
<div class="input-group-prepend">
<span class="input-group-text">Quality</span>
<span class="input-group-text w-100 justify-content-center">Quality</span>
</div>
<select class="form-control form-control-lg" id="torrent1">
<option value="1080" selected>1080p</option>
@ -975,6 +976,7 @@ wss://peertube.cpy.re:443/tracker/socket</textarea>
<option value='480"||"540'>SD</option>
</select>
</div>
<break></break>
<div class="custom-switch mb-10 pl-10 font-size-16 w-300" data-toggle="tooltip" data-placement="top"
data-title="Sends A Notification When A New Episode Is Released">
<input type="checkbox" id="other1">
@ -1079,6 +1081,7 @@ wss://peertube.cpy.re:443/tracker/socket</textarea>
</template>
<script src="https://cdn.jsdelivr.net/gh/halfmoonui/halfmoon@1.1.1/js/halfmoon.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anitomyscript@2.0.4/dist/anitomyscript.bundle.min.js"></script>
<script src="https://apis.google.com/js/api.js"></script>
<script src="js/bundle.js"></script>
</body>

View file

@ -1,5 +1,3 @@
/* eslint-env browser */
/* global */
import { alID } from './interface.js'
import halfmoon from 'halfmoon'

View file

@ -1,4 +1,3 @@
/* eslint-env browser */
/* global searchText */
import { client } from './main.js'
import { searchParams, DOMPARSER } from './util.js'
@ -179,6 +178,12 @@ export async function resolveFileMedia (opts) {
}
} else {
console.log('error in parsing!', opts.media, tempMedia)
halfmoon.initStickyAlert({
content: `Failed resolving anime episode!<br>${opts.media.title.userPreferred} - ${epMax}`,
title: 'Parsing Error',
alertType: 'alert-secondary',
fillType: ''
})
// something failed, most likely couldnt find an edge or processing failed, force episode number even if its invalid/out of bounds, better than nothing
if (opts.episode.constructor === Array) {
episode = `${Number(praseObj.episode_number[0])} ~ ${Number(praseObj.episode_number[praseObj.episode_number.length - 1])}`

View file

@ -17,8 +17,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var halfmoon__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! halfmoon */ "halfmoon");
/* harmony import */ var halfmoon__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(halfmoon__WEBPACK_IMPORTED_MODULE_1__);
/* provided dependency */ var console = __webpack_require__(/*! ./node_modules/console-browserify/index.js */ "./node_modules/console-browserify/index.js");
/* eslint-env browser */
/* global */
@ -328,7 +326,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var anitomyscript__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! anitomyscript */ "anitomyscript");
/* harmony import */ var anitomyscript__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(anitomyscript__WEBPACK_IMPORTED_MODULE_6__);
/* provided dependency */ var console = __webpack_require__(/*! ./node_modules/console-browserify/index.js */ "./node_modules/console-browserify/index.js");
/* eslint-env browser */
/* global searchText */
@ -509,6 +506,12 @@ async function resolveFileMedia (opts) {
}
} else {
console.log('error in parsing!', opts.media, tempMedia)
halfmoon__WEBPACK_IMPORTED_MODULE_5___default().initStickyAlert({
content: `Failed resolving anime episode!<br>${opts.media.title.userPreferred} - ${epMax}`,
title: 'Parsing Error',
alertType: 'alert-secondary',
fillType: ''
})
// something failed, most likely couldnt find an edge or processing failed, force episode number even if its invalid/out of bounds, better than nothing
if (opts.episode.constructor === Array) {
episode = `${Number(praseObj.episode_number[0])} ~ ${Number(praseObj.episode_number[praseObj.episode_number.length - 1])}`
@ -587,7 +590,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util.js */ "./app/js/util.js");
/* harmony import */ var halfmoon__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! halfmoon */ "halfmoon");
/* harmony import */ var halfmoon__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(halfmoon__WEBPACK_IMPORTED_MODULE_6__);
/* eslint-env browser */
/* global navHome, searchClear, searchWrapper, skeletonCardTemplate, bareCardTemplate, fullCardTemplate, home, searchText, searchGenre, searchYear, searchSeason, searchFormat, searchStatus, searchSort, navSchedule, homeContinueMore, homeReleasesMore, homePlanningMore, homeTrendingMore, homeRomanceMore, homeActionMore, homeContinue, homeReleases, homePlanning, homeTrending, homeRomance, homeAction */
// THIS IS WHY YOU FUCKING USE FRAMEWORKS
@ -695,20 +697,21 @@ function loadHomePage () {
const pubDate = doc.querySelector('pubDate').textContent
if (lastRSSDate !== pubDate) {
if (lastRSSDate) {
homeReleases.textContent = ''
homeReleases.append(...gallerySkeletonFrag(5))
;(0,_anime_js__WEBPACK_IMPORTED_MODULE_1__.resolveFileMedia)({ fileName: doc.querySelector('item title').textContent, isRelease: true }).then(mediaInformation => {
if (_settings_js__WEBPACK_IMPORTED_MODULE_3__.settings.other1) {
if (_settings_js__WEBPACK_IMPORTED_MODULE_3__.settings.other1) {
(0,_anime_js__WEBPACK_IMPORTED_MODULE_1__.resolveFileMedia)({ fileName: doc.querySelector('item title').textContent, isRelease: true }).then(mediaInformation => {
const notification = new Notification(mediaInformation.media.title.userPreferred, {
body: `Episode ${mediaInformation.episodeNumber} was just released!`,
icon: mediaInformation.media.coverImage.medium
})
notification.onclick = async () => {
window.parent.focus()
_main_js__WEBPACK_IMPORTED_MODULE_4__.client.playTorrent(doc.querySelector('item link').textContent, { media: mediaInformation, episode: mediaInformation.episode })
_anime_js__WEBPACK_IMPORTED_MODULE_1__.relations[mediaInformation.parseObject.anime_title] = (await (0,_anilist_js__WEBPACK_IMPORTED_MODULE_0__.alRequest)({ id: mediaInformation.media.id, method: 'SearchIDSingle' })).data.Media.id
_main_js__WEBPACK_IMPORTED_MODULE_4__.client.playTorrent(doc.querySelector('item link').textContent, { media: mediaInformation, episode: mediaInformation.episode })
}
}
})
})
}
}
lastRSSDate = pubDate
const cards = await releasesCards(doc.querySelectorAll('item'), 5)
@ -1232,7 +1235,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var halfmoon__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(halfmoon__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _anime_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./anime.js */ "./app/js/anime.js");
/* provided dependency */ var console = __webpack_require__(/*! ./node_modules/console-browserify/index.js */ "./node_modules/console-browserify/index.js");
/* eslint-env browser */
/* global torrent4list */
@ -1358,7 +1360,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ "settings": () => (/* binding */ settings)
/* harmony export */ });
/* harmony import */ var idb_keyval__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! idb-keyval */ "./node_modules/idb-keyval/dist/esm/index.js");
/* eslint-env browser */
/* global volume, player2, player3, player5, player6, player10, subtitle1, subtitle3, torrent1, torrent2, torrent3, torrent4, torrent5, torrent5label, torrent7, torrent8, torrent9, torrent10, other1, other2, setRes, settingsTab, regProtButton, clearRelCache */
const settingsElements = [
@ -1370,16 +1371,17 @@ volume.addEventListener('click', applySettingsTimeout)
regProtButton.addEventListener('click', registerProtocol)
const settings = JSON.parse(localStorage.getItem('settings')) || {}
const customStore = (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.createStore)('handle-store', 'handles')
let customStore
settings.torrent5 = (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.get)('directory', customStore).then(handle => {
if (handle) {
torrent5label.value = 'Folder: ' + handle.name
return handle
}
return null
})
if ('showDirectoryPicker' in window) {
customStore = (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.createStore)('handle-store', 'handles')
settings.torrent5 = (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.get)('directory', customStore).then(handle => {
if (handle) {
torrent5label.value = 'Folder: ' + handle.name
return handle
}
return null
})
torrent5.classList.remove('d-none')
torrent5.onclick = async () => {
const handle = await window.showDirectoryPicker()
@ -1402,10 +1404,7 @@ async function saveSettings () {
if (Object.keys(settings).length !== settingsElements.length + 1) {
saveSettings()
}
function restoreDefaults () {
localStorage.removeItem('settings')
location.reload()
}
let applyTimeout
function applySettingsTimeout () {
clearTimeout(applyTimeout)
@ -1422,8 +1421,14 @@ function registerProtocol () {
}
}
function restoreDefaults () {
localStorage.removeItem('settings')
location.reload()
}
clearRelCache.onclick = () => {
localStorage.removeItem('relations')
location.reload()
}
for (const setting of Object.entries(settings)) {
@ -1453,7 +1458,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ });
/* harmony import */ var halfmoon__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! halfmoon */ "halfmoon");
/* harmony import */ var halfmoon__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(halfmoon__WEBPACK_IMPORTED_MODULE_0__);
/* eslint-env browser */
;(halfmoon__WEBPACK_IMPORTED_MODULE_0___default().showModal) = id => {
const t = document.getElementById(id)
@ -78818,7 +78822,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
}
if ('PresentationRequest' in window) {
this.presentationRequest = new PresentationRequest(['lib/cast.html'])
this.presentationRequest.addEventListener('connectionavailable', this.initCast.bind(this))
this.presentationRequest.addEventListener('connectionavailable', e => this.initCast(e))
this.presentationConnection = null
navigator.presentation.defaultRequest = this.presentationRequest
this.presentationRequest.getAvailability().then(aval => {
@ -78861,7 +78865,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
this.fps = 23.976
this.video.addEventListener('loadedmetadata', () => {
if (this.currentFile.name.endsWith('.mkv') && ('requestVideoFrameCallback' in HTMLVideoElement.prototype)) {
if ('requestVideoFrameCallback' in HTMLVideoElement.prototype) {
this.fps = new Promise(resolve => {
const resolveFps = () => {
this.video.removeEventListener('timeupdate', resolveFps)
@ -79200,7 +79204,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
tracks.push(videostream.getVideoTracks()[0], videostream.getAudioTracks()[0])
}
for (const track of tracks) {
peer.pc.addTrack(track)
peer.pc.addTrack(track, videostream)
}
this.video.play() // video pauses for some reason
}
@ -79245,28 +79249,25 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
}
async getBurnIn (noSubs) {
if (this.burnIn) {
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d', { alpha: false })
let running = true
canvas.width = this.video.videoWidth
canvas.height = this.video.videoHeight
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d', { alpha: false })
let running = true
canvas.width = this.video.videoWidth
canvas.height = this.video.videoHeight
const renderFrame = () => {
if (running === true) {
context.drawImage(this.video, 0, 0)
if (!noSubs) context.drawImage(this.subtitleData.renderer?.canvas, 0, 0, canvas.width, canvas.height)
requestAnimationFrame(renderFrame)
}
const renderFrame = () => {
if (running === true) {
context.drawImage(this.video, 0, 0)
if (!noSubs) context.drawImage(this.subtitleData.renderer?.canvas, 0, 0, canvas.width, canvas.height)
requestAnimationFrame(renderFrame)
}
requestAnimationFrame(renderFrame)
const destroy = () => {
running = false
canvas.remove()
}
return { stream: canvas.captureStream(await this.fps), destroy }
}
return null
requestAnimationFrame(renderFrame)
const destroy = () => {
running = false
canvas.remove()
}
return { stream: canvas.captureStream(await this.fps), destroy }
}
toTS (sec, full) {
@ -79642,7 +79643,8 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
if (isAss) {
callback(subtitles)
} else {
for (const split of buffer.toString().split('\n\n')) {
const text = buffer.toString().replace(/\r/g, '')
for (const split of text.split('\n\n')) {
const match = split.match(regex)
if (match) {
match[1] = match[1].match(/.*[.,]\d{2}/)[0]

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,3 @@
/* eslint-env browser */
/* global navHome, searchClear, searchWrapper, skeletonCardTemplate, bareCardTemplate, fullCardTemplate, home, searchText, searchGenre, searchYear, searchSeason, searchFormat, searchStatus, searchSort, navSchedule, homeContinueMore, homeReleasesMore, homePlanningMore, homeTrendingMore, homeRomanceMore, homeActionMore, homeContinue, homeReleases, homePlanning, homeTrending, homeRomance, homeAction */
// THIS IS WHY YOU FUCKING USE FRAMEWORKS
@ -106,20 +105,21 @@ export function loadHomePage () {
const pubDate = doc.querySelector('pubDate').textContent
if (lastRSSDate !== pubDate) {
if (lastRSSDate) {
homeReleases.textContent = ''
homeReleases.append(...gallerySkeletonFrag(5))
resolveFileMedia({ fileName: doc.querySelector('item title').textContent, isRelease: true }).then(mediaInformation => {
if (settings.other1) {
if (settings.other1) {
resolveFileMedia({ fileName: doc.querySelector('item title').textContent, isRelease: true }).then(mediaInformation => {
const notification = new Notification(mediaInformation.media.title.userPreferred, {
body: `Episode ${mediaInformation.episodeNumber} was just released!`,
icon: mediaInformation.media.coverImage.medium
})
notification.onclick = async () => {
window.parent.focus()
client.playTorrent(doc.querySelector('item link').textContent, { media: mediaInformation, episode: mediaInformation.episode })
relations[mediaInformation.parseObject.anime_title] = (await alRequest({ id: mediaInformation.media.id, method: 'SearchIDSingle' })).data.Media.id
client.playTorrent(doc.querySelector('item link').textContent, { media: mediaInformation, episode: mediaInformation.episode })
}
}
})
})
}
}
lastRSSDate = pubDate
const cards = await releasesCards(doc.querySelectorAll('item'), 5)

View file

@ -1,4 +1,3 @@
/* eslint-env browser */
/* global torrent4list */
import { settings } from './settings.js'

View file

@ -1,4 +1,3 @@
/* eslint-env browser */
/* global volume, player2, player3, player5, player6, player10, subtitle1, subtitle3, torrent1, torrent2, torrent3, torrent4, torrent5, torrent5label, torrent7, torrent8, torrent9, torrent10, other1, other2, setRes, settingsTab, regProtButton, clearRelCache */
import { get, set, createStore } from 'idb-keyval'
export const settingsElements = [
@ -10,16 +9,17 @@ volume.addEventListener('click', applySettingsTimeout)
regProtButton.addEventListener('click', registerProtocol)
export const settings = JSON.parse(localStorage.getItem('settings')) || {}
const customStore = createStore('handle-store', 'handles')
let customStore
settings.torrent5 = get('directory', customStore).then(handle => {
if (handle) {
torrent5label.value = 'Folder: ' + handle.name
return handle
}
return null
})
if ('showDirectoryPicker' in window) {
customStore = createStore('handle-store', 'handles')
settings.torrent5 = get('directory', customStore).then(handle => {
if (handle) {
torrent5label.value = 'Folder: ' + handle.name
return handle
}
return null
})
torrent5.classList.remove('d-none')
torrent5.onclick = async () => {
const handle = await window.showDirectoryPicker()
@ -42,10 +42,7 @@ async function saveSettings () {
if (Object.keys(settings).length !== settingsElements.length + 1) {
saveSettings()
}
function restoreDefaults () {
localStorage.removeItem('settings')
location.reload()
}
let applyTimeout
function applySettingsTimeout () {
clearTimeout(applyTimeout)
@ -62,8 +59,14 @@ function registerProtocol () {
}
}
function restoreDefaults () {
localStorage.removeItem('settings')
location.reload()
}
clearRelCache.onclick = () => {
localStorage.removeItem('relations')
location.reload()
}
for (const setting of Object.entries(settings)) {

View file

@ -1,4 +1,3 @@
/* eslint-env browser */
import halfmoon from 'halfmoon'
halfmoon.showModal = id => {
const t = document.getElementById(id)

View file

@ -24,14 +24,14 @@ const video = document.querySelector('video')
function addConnection (connection) {
peer = new window.Peer({ polite: false })
const stream = new MediaStream()
video.srcObject = stream
peer.pc.ontrack = evt => {
stream.addTrack(evt.track)
video.volume = 1
video.muted = false
video.play()
evt.receiver.playoutDelayHint = 3
if (!video.srcObject) {
video.srcObject = evt.streams[0]
video.volume = 1
video.play()
}
}
// only used to signal description and candidates to the other peer

View file

@ -33,7 +33,8 @@
"ignore": [
"bundle.js",
"bundle.map.js"
]
],
"env": "browser"
},
"devDependencies": {
"node-polyfill-webpack-plugin": "^1.1.4",

View file

@ -5,7 +5,8 @@ module.exports = {
entry: './app/js/main.js',
externals: {
halfmoon: 'halfmoon',
anitomyscript: 'anitomyscript'
anitomyscript: 'anitomyscript',
gapi: 'commonjs gapi'
},
output: {
filename: 'bundle.js',