12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232 |
- /* global $ */
- const MAX_PER_PAGE = 5
- const { electron, BrowserWindow, remote, ipcRenderer, shell, dialog, clipboard } = require('electron')
- const fs = require('fs')
- const path = require('path')
- const appSettings = remote.require('electron-settings')
- const isDev = remote.getGlobal('isDev')
- const LiveMe = remote.getGlobal('LiveMe')
- const DataManager = remote.getGlobal('DataManager')
- const formatDuration = require('format-duration')
- const prettydate = require('pretty-date')
- const request = require('request')
- let currentUser = {}
- let currentPage = 1
- let currentIndex = 0
- let tempvar = null
- let hasMore = false
- let currentSearch = ''
- let scrollBusy = false
- let currentView = 'home'
- $(function () {
- document.title = 'LiveMe Pro Tools v' + remote.app.getVersion() // Set Title of Window
- setupContextMenu() // Set up the Context Menu for Cut/Copy/Paste on text fields
- onTypeChange() // Init Search Field
- setupIPCListeners() // Set up our IPC listeners
- setupLoadOnScroll() // Setup loading more on scroll only when searching for usernames
- initSettingsPanel()
- // Authenticate if credentials saved
- if (appSettings.get('auth.email') && appSettings.get('auth.password')) {
- LiveMe.setAuthDetails(appSettings.get('auth.email').trim(), appSettings.get('auth.password').trim())
- }
- initHome()
-
- // Store Bookmarks, History and more every 2 minutes (120,000ms) in case of a crash or something
- setInterval(() => {
- DataManager.saveToDisk()
- }, 120000)
- })
- function setupContextMenu () {
- const InputMenu = remote.Menu.buildFromTemplate([{
- label: 'Undo',
- role: 'undo'
- }, {
- label: 'Redo',
- role: 'redo'
- }, {
- type: 'separator'
- }, {
- label: 'Cut',
- role: 'cut'
- }, {
- label: 'Copy',
- role: 'copy'
- }, {
- label: 'Paste',
- role: 'paste'
- }, {
- type: 'separator'
- }, {
- label: 'Select all',
- role: 'selectall'
- }
- ])
- document.body.addEventListener('contextmenu', (e) => {
- e.preventDefault()
- e.stopPropagation()
- let node = e.target
- while (node) {
- if (node.nodeName.match(/^(input|textarea)$/i) || node.isContentEditable) {
- InputMenu.popup(remote.getCurrentWindow())
- break
- }
- node = node.parentNode
- }
- })
- }
- function setupLoadOnScroll () {
- $('main').scroll(function () {
- if (($(this).scrollTop() + $(this).height()) > ($('table').height() - 80)) {
- if (hasMore === false) return
- if (scrollBusy === true) return
- scrollBusy = true
- currentPage++
- if (currentSearch === 'performUsernameSearch') {
- performUsernameSearch()
- } else if (currentSearch === 'performHashtagSearch') {
- _performHashtagSearch()
- } else {
- scrollBusy = false
- }
- }
- })
- }
- function setupIPCListeners () {
- ipcRenderer.on('show-user', (event, arg) => {
- $('#search-query').val(arg.userid)
- $('#search-type').val('user-id')
- doSearch()
- })
- ipcRenderer.on('popup-message', (event, arg) => {
- let p = $('#popup-message')
- p.html(arg.text).animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - p.height() }, 400)
- })
- ipcRenderer.on('go-home', (event, arg) => {
- goHome()
- })
- ipcRenderer.on('shutdown', (event, arg) => {
- $('overlay').show()
- $('#status').html('Storing data and shutting down...')
- })
- ipcRenderer.on('download-start', (event, arg) => {
- if ($('#download-' + arg.videoid).length < 1) return
- $('#download-' + arg.videoid).addClass('active')
- $('#download-' + arg.videoid + ' .status').html('Starting download..')
- $('#download-' + arg.videoid + ' .filename').html(arg.filename)
- $('#download-' + arg.videoid + ' .cancel').remove()
- })
- ipcRenderer.on('download-progress', (event, arg) => {
- if ($('#download-' + arg.videoid).length < 1) return
- $('#download-' + arg.videoid + ' .status').html(arg.state)
- $('#download-' + arg.videoid + ' .progress-bar .bar').css('width', arg.percent + '%')
- })
- ipcRenderer.on('download-complete', (event, arg) => {
- if ($('#download-' + arg.videoid).length < 1) return
- $('#download-' + arg.videoid).remove()
- })
- ipcRenderer.on('download-error', (event, arg) => {
- if ($('#download-' + arg.videoid).length < 1) return
- $('#download-' + arg.videoid + ' .status').html('Download Error<span></span>')
- $('#download-' + arg.videoid).append(`<div onClick="cancelDownload('${arg.videoid}')" class="cancel">✕</div>`)
- })
- }
- function showMainMenu () {
- const MainAppMenu = remote.Menu.buildFromTemplate(
- [
- /*
- {
- label: 'Import',
- submenu: [
- {
- label: 'ReplayID List to Download',
- click: () => importReplayIDList()
- },
- {
- label: 'UserID List to Favorites',
- click: () => importUserIDList()
- }
- ]
- },
- {
- label: 'Export',
- submenu: [
- {
- label: 'Favorites List',
- click: () => ExportFavorites()
- }
- ]
- }, */
- {
- label: 'Backup/Restore',
- submenu: [
- {
- label: 'Backup Data',
- click: () => backupData()
- },
- {
- label: 'Restore Data',
- click: () => restoreData()
- }
- ]
- },
- {
- type: 'separator'
- },
- {
- label: 'Open Bookmarks',
- click: () => openBookmarks()
- },
- {
- type: 'separator'
- },
- {
- label: 'Help',
- submenu: [
- {
- label: 'NotABug Git Home',
- click: () => shell.openExternal('https://notabug.org/thecoder1975/liveme-pro-tools/')
- },
- {
- label: 'Report an Issue on Discord',
- click: () => shell.openExternal('https://discord.gg/vKwR3WB')
- }
- ]
- },
- {
- type: 'separator'
- },
- {
- label: 'Settings',
- click: () => showSettings()
- },
- {
- type: 'separator'
- },
- {
- label: 'Quit',
- click: () => remote.app.quit()
- }
- ]
- )
- MainAppMenu.popup(
- remote.getCurrentWindow(),
- {
- x: 0,
- y: 40
- }
- )
- }
- function onTypeChange () {
- let t = $('#search-type').val()
- switch (t) {
- case 'user-id':
- $('#search-query').attr('placeholder', 'User ID')
- break
- case 'short-id':
- $('#search-query').attr('placeholder', 'Short ID')
- break
- case 'video-id':
- $('#search-query').attr('placeholder', 'Video ID')
- break
- case 'video-url':
- $('#search-query').attr('placeholder', 'Video URL')
- break
- case 'hashtag':
- $('#search-query').attr('placeholder', 'Enter a hashtag')
- break
- case 'username-like':
- $('#search-query').attr('placeholder', 'Partial or Full Username')
- break
- }
- }
- function closeOverlay () {
- if ($('#queue-list').is(':visible')) {
- $('#queue-list').hide()
- $('overlay').hide()
- }
- }
- function enterOnSearch (e) { if (e.keyCode === 13) preSearch() }
- function copyToClipboard (i) { clipboard.writeText(i) }
- function showSettings () { $('#settings').show() }
- function hideSettings () { $('#settings').hide() }
- function closeWindow () { window.close() }
- function minimizeWindow () { remote.BrowserWindow.getFocusedWindow().minimize() }
- function showProgressBar () { $('#footer-progressbar').show() }
- function hideProgressBar () { $('#footer-progressbar').hide() }
- function setProgressBarValue (v) { $('#footer-progressbar div').css({ width: v + '%' }) }
- function showUser (u) {
- $('#search-type').val('user-id')
- $('#search-query').val(u)
- $('overlay').show()
- setTimeout(function () { preSearch() }, 500)
- }
- function openBookmarks () { ipcRenderer.send('open-bookmarks') }
- function showFollowing (u) { ipcRenderer.send('open-followings-window', { userid: currentUser.uid !== undefined ? currentUser.uid : u }) }
- function showFollowers (u) { ipcRenderer.send('open-followers-window', { userid: currentUser.uid !== undefined ? currentUser.uid : u }) }
- function playVideo (vid) { ipcRenderer.send('watch-replay', { videoid: vid }) }
- function sortReplays (name) {
- $('table#list tbody tr').sort(function (a, b) {
- var aValue = $(a).find('td[data-name="' + name + '"]').text()
- var bValue = $(b).find('td[data-name="' + name + '"]').text()
- if (name === 'date') {
- aValue = new Date(aValue).getTime()
- bValue = new Date(bValue).getTime()
- }
- return ((+aValue < +bValue) ? 1 : ((+aValue > +bValue) ? -1 : 0))
- }).appendTo('table#list tbody')
- if (hasMore) {
- setTimeout(() => sortReplays(name), 500)
- }
- }
- function downloadVideo (vid) {
- $('#download-replay-' + vid).html('<i class="icon icon-download dim"></i>')
- $('#download-replay-' + vid).unbind()
- if (appSettings.get('lamd.handle_downloads') === true) {
- AddReplayToLAMD(vid)
- } else {
- ipcRenderer.send('download-replay', { videoid: vid })
- if ($('#download-' + vid).length > 0) return
- $('#queue-list').append(`
- <div class="download" id="download-${vid}">
- <div class="filename">${vid}</div>
- <div class="status">Queued</div>
- <div class="progress-bar">
- <div class="bar" style="width: 0%"></div>
- </div>
- <div onClick="cancelDownload('${vid}')" class="cancel">✕</div>
- </div>
- `)
- }
- }
- function cancelDownload (i) {
- ipcRenderer.send('download-cancel', { videoid: i })
- $('#download-' + i).remove()
- }
- function showDownloads () {
- if ($('#queue-list').is(':visible')) {
- $('overlay').hide()
- $('#queue-list').hide()
- } else {
- $('overlay').show()
- $('#queue-list').show()
- }
- }
- function importReplayIDList () { ipcRenderer.send('import-queue') }
- function importUserIDList () { ipcRenderer.send('import-users') }
- function ExportFavorites () { ipcRenderer.send('export-users') }
- function openURL (u) { shell.openExternal(u) }
- function readComments (u) { ipcRenderer.send('read-comments', { userid: u }) }
- function goHome () {
- $('footer').hide()
- $('main').hide()
- $('#home').show()
- $('overlay').hide()
- $('#queue-list').hide()
- currentView = 'home'
- initHome()
- }
- function preSearch (q) {
- let u = $('#search-query').val()
- let isnum = /^\d+$/.test(u)
- $('overlay').hide()
- $('#queue-list').hide()
- currentView = 'search'
- if ((u.length === 20) && (isnum)) {
- if ($('#search-type').val() !== 'video-id') {
- $('#search-type').val('video-id')
- onTypeChange()
- }
- } else if ((u.length === 18) && (isnum)) {
- if ($('#search-type').val() !== 'user-id') {
- $('#search-type').val('user-id')
- onTypeChange()
- }
- } else if (((u.length === 8) || (u.length === 9)) && (isnum)) {
- if ($('#search-type').val() !== 'short-id') {
- $('#search-type').val('short-id')
- onTypeChange()
- }
- } else if (u.indexOf('http') > -1) {
- if ($('#search-type').val() !== 'video-url') {
- $('#search-type').val('video-url')
- onTypeChange()
- }
- } else if (u.indexOf('#') > -1) {
- if ($('#search-type').val() !== 'hashtag') {
- $('#search-type').val('hashtag')
- $('#search-query').val($('#search-query').val().replace('#', ''))
- onTypeChange()
- }
- } else if (!isnum) {
- if ($('#search-type').val() !== 'username-like') {
- $('#search-type').val('username-like')
- onTypeChange()
- }
- }
- doSearch()
- }
- function AddToBookmarks () {
- if (DataManager.isBookmarked(currentUser) === true) {
- DataManager.removeBookmark(currentUser)
- $('a.bookmark').attr('title', 'Add to Bookmarks').html('<i class="icon icon-star-empty"></i>')
- } else {
- DataManager.addBookmark(currentUser)
- $('a.bookmark').attr('title', 'Remove from Bookmarks').html('<i class="icon icon-star-full bright yellow"></i>')
- }
- }
- function backupData () {
- ipcRenderer.send('create-backup')
- let p = $('#popup-message')
- let m = 'Backup file stored in your downloads.'
- p.html(m).animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - p.height() - 20 }, 400)
- }
- function restoreData () {
- ipcRenderer.send('restore-backup')
- }
- function initHome () {
- $('#home div.panel').html('')
- // Check for updates
- request({
- url: 'https://notabug.org/thecoder1975/liveme-pro-tools/raw/master/package.json',
- method: 'get'
- }, (err, httpResponse, body) => {
- if (!err) {
- let ghversion = JSON.parse(body).version
- let lversion = remote.app.getVersion()
- let g = ghversion.split('.')
- let ghv = g[0] + '' + g[1]
- let l = lversion.split('.')
- let lv = l[0] + '' + l[1]
- let upgrade = (g[0] - l[0]) + (g[1] - l[1])
- if (upgrade > 0) {
- if ($('#home div.panel .section').length < 1) {
- $('#home div.panel').empty()
- }
- $('#home div.panel').append(`
- <div class="section">
- <h3><i class="icon icon-download"></i> Update Available</h3>
- <p>
- An updated release of LiveMe Pro Tools is available.
- </p>
- <button onClick="openURL('https://notabug.org/thecoder1975/liveme-pro-tools/releases/')">Download</button>
- </div>
- `)
- }
- }
- })
- $('footer h1').html('Bookmarks are now being scanned for new replays...')
- $('#home').show()
- var bookmarks = DataManager.getAllBookmarks()
- tempvar = {
- index: 0,
- max: bookmarks.length,
- list: bookmarks
- }
- $('#home #bookmarklist').empty()
- setTimeout(() => {
- _homethread()
- }, 50)
- }
- function _homethread () {
- setImmediate(() => {
- if (tempvar.index < tempvar.max) {
- setTimeout(() => _homethread(), 50)
- }
- if (tempvar.index < tempvar.max - 1) { tempvar.index++; _checkBookmark(tempvar.list[tempvar.index].uid) }
- if (tempvar.index < tempvar.max - 1) { tempvar.index++; _checkBookmark(tempvar.list[tempvar.index].uid) }
- })
- }
- function _checkBookmark (uid) {
- if (uid === undefined) return
- if (!LiveMe.user) {
- return setTimeout(() => _checkBookmark(), 5000)
- }
- LiveMe.getUserInfo(uid).then(user => {
- if (user === undefined) return
- let b = DataManager.getSingleBookmark(user.user_info.uid)
- let dt = new Date()
- b.counts.replays = user.count_info.video_count
- b.counts.friends = user.count_info.friends_count
- b.counts.followers = user.count_info.follower_count
- b.counts.followings = user.count_info.following_count
- b.signature = user.user_info.usign
- b.sex = user.user_info.sex
- b.face = user.user_info.face
- b.nickname = user.user_info.uname
- b.shortid = user.user_info.short_id
- DataManager.updateBookmark(b)
- if (b.counts.replays > 0) {
- LiveMe.getUserReplays(uid, 1, 2)
- .then(replays => {
- if (replays === undefined) return
- if (replays.length < 1) return
- let count = 0
- let userid = replays[0].userid
- let bookmark = DataManager.getSingleBookmark(userid)
- for (let i = 0; i < replays.length; i++) {
- if (replays[i].vtime - bookmark.newest_replay > 0) {
- let latest = prettydate.format(new Date(replays[0].vtime * 1000))
- let last = prettydate.format(new Date(bookmark.last_viewed * 1000))
- bookmark.newest_replay = Math.floor(replays[0].vtime)
- DataManager.updateBookmark(bookmark)
- if (currentView === 'home') {
- $('#home #bookmarklist').append(`
- <div class="bookmark" id="bookmark-${bookmark.uid}" onClick="showUser('${bookmark.uid}')">
- <img src="${bookmark.face}" class="avatar" onError="$(this).hide()">
- <h1>${bookmark.nickname}</h1>
- <h3>Newest replay posted ${latest}</h3>
- <h2>NEW</h2>
- </div>
- `)
- }
- break
- }
- }
- })
- .catch(error => {
- // Unhandled error occured
-
- })
- }
- })
- }
- function saveAccountFace () {
- let u = appSettings.get('downloads.path')
- request.get(currentUser.face)
- .on('error', () => { })
- .pipe(fs.createWriteStream(`${u}/${currentUser.uid}.jpg`))
- $('#popup-message').html('Image saved to downloads.').animate({ top: 40 }, 400).delay(2000).animate({ top: 0 - $('#popup-message').height() }, 400)
- }
- function doSearch () {
- let query = ''
- let userid = ''
- let q = $('#search-query').val()
- if (q.length < 1) return
- $('#user-details').hide()
- $('main').hide().removeClass('has-panel')
- $('#status').show().html('Performing LiveMe Search...')
- $('#home').hide()
- currentPage = 1
- $('#list tbody').html('')
- switch ($('#search-type').val()) {
- case 'video-url':
- let t = q.split('/')
- if (q.indexOf('/live/') > -1) {
- query = q[3]
- performVideoLookup(query)
- } else if (q[q.length - 1].indexof('yolo') > -1) {
- let a = q[q.length - 1].split('-')
- $('#search-query').val(a[1])
- $('#search-type').val('video-id')
- query = a[1]
- performVideoLookup(query)
- } else if (q.indexOf('videoid') > -1) {
- let a = t[t.length - 1].split('?')
- let b = a[1].split('&')
- for (let i = 0; i < b.length; i++) {
- if (b[i].indexOf('videoid') > -1) {
- let c = b[i].split('=')
- query = c[1]
- $('#search-query').val(c[1])
- $('#search-type').val('video-id')
- }
- }
- performVideoLookup(query)
- } else if (q.indexOf('userid') > -1) {
- let a = t[t.length - 1].split('?')
- let b = a[1].split('&')
- for (let i = 0; i < b.length; i++) {
- if (b[i].indexOf('userid') > -1) {
- let c = b[i].split('=')
- query = c[1]
- $('#search-query').val(c[1])
- $('#search-type').val('user-id')
- }
- }
- performUserLookup(query)
- }
- break
- case 'video-id':
- performVideoLookup($('#search-query').val())
- break
- case 'user-id':
- performUserLookup($('#search-query').val())
- break
- case 'short-id':
- performShortIDSearch()
- break
- case 'hashtag':
- $('main').show().removeClass('has-details')
- $('#user-details').hide()
- $('#list').show()
- $('#list thead').html('')
- performHashtagSearch()
- break
- case 'username-like':
- $('main').show().removeClass('has-details')
- $('#list thead').html('')
- performUsernameSearch()
- break
- }
- }
- function performShortIDSearch () {
- LiveMe.performSearch($('#search-query').val(), 1, 1, 1).then(results => {
- if (results.length > 0) {
- performUserLookup(results[0].user_id)
- }
- })
- }
- function performVideoLookup (q) {
- LiveMe.getVideoInfo(q)
- .then(video => {
- if (video.videosource.length < 1) {
- $('#status').html('Video not found or was deleted from the servers.')
- $('overlay').hide()
- $('main').hide()
- } else {
- _addReplayEntry(video, true)
- performUserLookup(video.userid)
- }
- }).catch(() => {
- $('#status').html('Video not found or was deleted from the servers.')
- $('overlay').hide()
- $('main').hide()
- })
- }
- function performUserLookup (uid) {
- LiveMe.getUserInfo(uid)
- .then(user => {
- let bookmark = DataManager.getSingleBookmark(user.user_info.uid)
- if (bookmark !== false) {
- bookmark.last_viewed = Math.floor(new Date().getTime() / 1000)
- DataManager.updateBookmark(bookmark)
- }
- DataManager.addViewed(user.user_info.uid)
- $('#list thead').html(`
- <tr>
- <th width="410">Title</th>
- <th width="120">
- <a href="#" class="link text-center" onClick="sortReplays('date')" title="Sort by Date (desc)">Date</a>
- </th>
- <th width="50" align="right">Length</th>
- <th width="70" align="right">
- <a href="#" class="link text-right" onClick="sortReplays('views')" title="Sort by Views (desc)">Views</a>
- </th>
- <th width="70" align="right">
- <a href="#" class="link text-right" onClick="sortReplays('likes')" title="Sort by Likes (desc)">Likes</a>
- </th>
- <th width="70" align="right">
- <a href="#" class="link text-right" onClick="sortReplays('shares')" title="Sort by Shares (desc)">Shares</a>
- </th>
- <th width="210">Actions</th>
- </tr>
- `)
- let sex = user.user_info.sex < 0 ? '' : (user.user_info.sex === 0 ? 'female' : 'male')
- $('#user-details').show()
- $('img.avatar').attr('src', user.user_info.face)
- $('#user-details div.info h1 span').html(user.user_info.uname)
- $('#user-details div.info h2.id').html('<span>ID:</span> ' + user.user_info.uid + ' <a class="button icon-only" title="Copy to Clipboard" onClick="copyToClipboard(\'' + user.user_info.uid + '\')"><i class="icon icon-copy"></i></a>')
- $('#user-details div.info h2.shortid').html('<span>Short ID:</span> ' + user.user_info.short_id + ' <a class="button icon-only" title="Copy to Clipboard" onClick="copyToClipboard(\'' + user.user_info.uid + '\')"><i class="icon icon-copy"></i></a>')
- $('#user-details div.info h2.level').html('<span>Level:</span><b>' + user.user_info.level + '</b>')
- $('#user-details div.info h4').html(user.user_info.countryCode)
- if (DataManager.isBookmarked(user.user_info) === true) {
- $('#user-details a.bookmark').attr('title', 'Remove from Bookmarks').html('<i class="icon icon-star-full bright yellow"></i>')
- } else {
- $('#user-details a.bookmark').attr('title', 'Add to Bookmarks').html('<i class="icon icon-star-empty"></i>')
- }
- $('#user-details div.info a.following').html('Following ' + user.count_info.following_count)
- $('#user-details div.info a.followers').html(user.count_info.follower_count + ' Followers')
- setTimeout(() => {
- $('#status').hide()
- $('overlay').hide()
- $('main').show()
- }, 250)
- currentPage = 1
- currentUser = {
- uid: user.user_info.uid,
- shortid: user.user_info.short_id,
- signature: user.user_info.usign,
- sex: sex,
- face: user.user_info.face,
- nickname: user.user_info.uname,
- counts: {
- replays: user.count_info.video_count,
- friends: user.count_info.friends_count,
- followers: user.count_info.follower_count,
- followings: user.count_info.following_count
- },
- last_viewed: Math.floor((new Date()).getTime() / 1000),
- newest_replay: 0
- }
- getUsersReplays()
- showProgressBar()
- })
- .catch(() => {
- $('#status').html('Account no longer available.')
- })
- }
- function getUsersReplays () {
- if (!LiveMe.user) {
- $('#replay-result-alert').html('<span>Error!</span> You are not authenticated, please enter your login details under Settings.').fadeIn(200)
- return setTimeout(() => getUsersReplays(), 5000)
- } else {
- $('#replay-result-alert').hide()
- }
- LiveMe.getUserReplays(currentUser.uid, currentPage, MAX_PER_PAGE)
- .then(replays => {
-
- if ((typeof replays === 'undefined') || (replays == null)) {
- if (currentPage === 1) {
- $('#replay-result-alert').html('<span>No replays!</span> There is no publicly listed replays available.').fadeIn(200)
- $('footer h1').html('No publicly listed replays available.')
- hideProgressBar()
- }
- return
- }
- if (replays.length > 0) {
- if (replays[0].uid === currentUser.userid) {
- for (let i = 0; i < replays.length; i++) {
- _addReplayEntry(replays[i], false)
- }
- }
- }
- $('#list tbody tr').not('.user-' + currentUser.uid).remove()
- $('footer h1').html($('#list tbody tr').length + ' visible of ' + currentUser.counts.replays + ' total replays loaded.')
- setProgressBarValue(($('#list tbody tr').length / currentUser.counts.replays) * 100)
- hasMore = replays.length === MAX_PER_PAGE
- currentSearch = 'getUsersReplays'
- if (hasMore === true) {
- setTimeout(() => {
- currentPage++
- getUsersReplays()
- }, 500)
- } else {
- let c = $('#list tbody tr td.highlight').length
- let d = $('#list tbody tr').length
- if (c.length === 0) {
- $('#list table tbody tr.unlisted').removeClass('unlisted')
- } else {
- $('#list table tbody tr.unlisted').remove()
- $('footer h1').html($('#list tbody tr').length + ' visible of ' + currentUser.counts.replays + ' total replays loaded.')
- }
- if (d === 0) $('footer h1').html('No publicly listed replays available.')
- hideProgressBar()
- }
- })
- .catch(error => {
- // Unhandled error
-
- })
- }
- function _addReplayEntry (replay, wasSearched) {
- if (replay.userid !== currentUser.uid) return
- if (replay.vtime > currentUser.newest_replay) currentUser.newest_replay = replay.vtime
- let dt = new Date(replay.vtime * 1000)
- let ds = (dt.getMonth() + 1) + '-' + dt.getDate() + '-' + dt.getFullYear() + ' ' + (dt.getHours() < 10 ? '0' : '') + dt.getHours() + ':' + (dt.getMinutes() < 10 ? '0' : '') + dt.getMinutes()
- let highlight = $('#search-type').val() === 'video-id' ? ($('#search-query').val() === replay.vid ? 'highlight' : '') : ''
- let length = formatDuration(parseInt(replay.videolength) * 1000)
- let searched = wasSearched ? 'unlisted' : ''
- let unlisted = searched ? '[UNLISTED]' : ''
- let downloadDate = DataManager.wasDownloaded(replay.vid)
- let watchDate = DataManager.wasWatched(replay.vid)
- let downloaded = downloadDate === false ? '<i class="icon icon-floppy-disk dim"></i>' : '<i class="icon icon-floppy-disk bright blue" title="Downloaded ' + prettydate.format(downloadDate) + '"></i>'
- let watched = watchDate === false ? '<i class="icon icon-eye dim"></i>' : '<i class="icon icon-eye bright green" title="Last watched ' + prettydate.format(watchDate) + '"></i>'
- let seen = watchDate === false ? '' : 'watched'
- let isLive = replay.hlsvideosource.endsWith('flv') || replay.hlsvideosource.indexOf('liveplay') > 0 ? '<b style="color:limegreen;">[LIVE]</b>' : ''
- let inQueue = $('#download-' + replay.vid).length > 0 ? '<a id="download-replay-' + replay.vid + '" class="button icon-only" title="Download Replay"><i class="icon icon-download dim"></i></a>' : '<a id="download-replay-' + replay.vid + '" class="button icon-only" onClick="downloadVideo(\'' + replay.vid + '\')" title="Download Replay"><i class="icon icon-download"></i></a>'
- const template = Handlebars.compile($('#replays-list-row').html())
- const html = template(
- Object.assign(replay, {
- searched,
- seen,
- highlight,
- watched,
- downloaded,
- unlisted,
- isLive,
- length,
- ds,
- inQueue,
- source: replay.videosource || replay.hlsvideosource
- })
- )
- /*
- let h = `
- <tr data-id="${replay.vid}" class="${searched} ${seen} user-${replay.userid}">
- <td width="410" class="${highlight}">${watched} ${downloaded} ${unlisted}${isLive}${replay.title}</td>
- <td width="120" class="${highlight}" align="center">${ds}</td>
- <td width="50" class="${highlight}" align="right">${length}</td>
- <td width="70" class="${highlight}" align="right">${replay.playnumber}</td>
- <td width="70" class="${highlight}" align="right">${replay.likenum}</td>
- <td width="70" class="${highlight}" align="right">${replay.sharenum}</td>
- <td width="300" class="${highlight}" style="padding: 0 16px; text-align: right;">
- <a class="button mini icon-small" onClick="copyToClipboard('${replay.vid}')" style="font-size: 10pt;" title="Copy ID to Clipboard">ID</a>
-
- <a class="button mini icon-small" onClick="copyToClipboard('https://www.liveme.com/live.html?videoid=${replay.vid}')" href="#" style="font-size: 10pt;" title="Copy URL to Clipboard">URL</a>
-
- <a class="button mini icon-small" onClick="copyToClipboard('${replay.videosource || replay.hlsvideosource}')" style="font-size: 10pt;" title="Copy Source to Clipboard (m3u8 or flv)">Source</a>
-
- <a class="button icon-only" onClick="playVideo('${replay.vid}')" title="Watch Replay"><i class="icon icon-play"></i></a>
- <a class="button icon-only" onClick="readComments('${replay.vid}')" title="Read Comments"><i class="icon icon-bubbles3"></i></a>
- ${inQueue}
- </td>
- </tr>
- `
- */
- const item = $(html).hide().fadeIn(200)
- $('#list tbody').append(item)
- }
- function performUsernameSearch () {
- LiveMe.performSearch($('#search-query').val(), currentPage, MAX_PER_PAGE, 1)
- .then(results => {
- currentSearch = 'performUsernameSearch'
- hasMore = results.length >= MAX_PER_PAGE
- setTimeout(function () { scrollBusy = false }, 250)
- for (var i = 0; i < results.length; i++) {
- let bookmarked = DataManager.isBookmarked(results[i].user_id) ? '<i class="icon icon-star-full bright yellow"></i>' : '<i class="icon icon-star-full dim"></i>'
- let viewed = DataManager.wasProfileViewed(results[i].user_id)
- ? '<i class="icon icon-eye bright blue" title="Last viewed ' + prettydate.format(DataManager.wasProfileViewed(results[i].user_id)) + '"></i>'
- : '<i class="icon icon-eye dim"></i>'
- var sex = results[i].sex < 0 ? '' : (results[i].sex == 0 ? 'female' : 'male');
-
- $('#list tbody').append(`
- <tr id="user-${results[i].user_id}" class="user-search ${sex}">
- <td width="128" style="text-align: center;">
- <img src="${results[i].face}" style="height: 128px; width: 128px;" onError="$(this).hide()">
- </td>
- <td width="896" class="details">
- <h4>${results[i].nickname}</h4>
- <h5 class="userid"></h5>
- <h5 class="shortid"></h5>
- <h5 class="level"></h5>
- <h5 class="country"></h5>
- <div class="bookmarked">${bookmarked}</div>
- <div class="viewed">${viewed}</div>
- <a class="button replays" onClick="showUser('${results[i].user_id}')">0 Replays</a>
- <a class="button followings" onClick="showFollowing('${results[i].user_id}')">Following 0</a>
- <a class="button followers" onClick="showFollowers('${results[i].user_id}')">0 Fans</a>
- </td>
- </tr>
- `)
- LiveMe.getUserInfo(results[i].user_id)
- .then(user => {
- if (user === undefined) return
- if (user === null) return
- $('#user-' + user.user_info.uid + ' td.details a.replays').html(`${user.count_info.video_count} Replays`)
- $('#user-' + user.user_info.uid + ' td.details a.followings').html(`Following ${user.count_info.following_count}`)
- $('#user-' + user.user_info.uid + ' td.details a.followers').html(`${user.count_info.follower_count} Fans`)
- $('#user-' + user.user_info.uid + ' td.details h5.userid').html(`ID: <span>${user.user_info.uid}<a class="button icon-only" title="Copy to Clipboard" onClick="copyToClipboard('${user.user_info.uid}')"><i class="icon icon-copy"></i></a></span>`)
- $('#user-' + user.user_info.uid + ' td.details h5.shortid').html(`Short ID: <span>${user.user_info.short_id}<a class="button icon-only" title="Copy to Clipboard" onClick="copyToClipboard('${user.user_info.short_id}')"><i class="icon icon-copy"></i></a></span>`)
- $('#user-' + user.user_info.uid + ' td.details h5.level').html(`Level: <span>${user.user_info.level}</span>`)
- $('#user-' + user.user_info.uid + ' td.details h5.country').html(`${user.user_info.countryCode}`)
- })
- $('footer h1').html($('#list tbody tr').length + ' accounts found so far, scroll down to load more.')
- }
- if (results.length === 0 && currentPage === 1) {
- $('#status').html('No users were found searching for ' + $('#search-query').val()).show()
- } else {
- $('#status').hide()
- }
- })
- }
- function performHashtagSearch() {
-
- $('#list thead').html(`
- <tr>
- <th width="410">Title</th>
- <th width="120">
- <a href="#" class="link text-center" onClick="sortReplays('date')" title="Sort by Date (desc)">Date</a>
- </th>
- <th width="50" align="right">Length</th>
- <th width="70" align="right">
- <a href="#" class="link text-right" onClick="sortReplays('views')" title="Sort by Views (desc)">Views</a>
- </th>
- <th width="70" align="right">
- <a href="#" class="link text-right" onClick="sortReplays('likes')" title="Sort by Likes (desc)">Likes</a>
- </th>
- <th width="70" align="right">
- <a href="#" class="link text-right" onClick="sortReplays('shares')" title="Sort by Shares (desc)">Shares</a>
- </th>
- <th width="210">Actions</th>
- </tr>
- `)
- setTimeout(() => {
- _performHashtagSearch()
- }, 100);
- }
- function _performHashtagSearch() {
- LiveMe.performSearch($('#search-query').val(), currentPage, MAX_PER_PAGE, 2)
- .then(results => {
-
- currentSearch = 'performHashtagSearch'
- hasMore = results.length >= MAX_PER_PAGE
- setTimeout(function () { scrollBusy = false }, 250)
- for (var i = 0; i < results.length; i++) {
-
- let dt = new Date(results[i].vtime * 1000)
- let ds = (dt.getMonth() + 1) + '-' + dt.getDate() + '-' + dt.getFullYear() + ' ' + (dt.getHours() < 10 ? '0' : '') + dt.getHours() + ':' + (dt.getMinutes() < 10 ? '0' : '') + dt.getMinutes()
- let length = formatDuration(parseInt(results[i].videolength) * 1000)
- let downloadDate = DataManager.wasDownloaded(results[i].vid)
- let watchDate = DataManager.wasWatched(results[i].vid)
- let downloaded = downloadDate === false ? '<i class="icon icon-floppy-disk dim"></i>' : '<i class="icon icon-floppy-disk bright blue" title="Downloaded ' + prettydate.format(downloadDate) + '"></i>'
- let watched = watchDate === false ? '<i class="icon icon-eye dim"></i>' : '<i class="icon icon-eye bright green" title="Last watched ' + prettydate.format(watchDate) + '"></i>'
- let seen = watchDate === false ? '' : 'watched'
- let isLive = results[i].hlsvideosource.endsWith('flv') || results[i].hlsvideosource.indexOf('liveplay') > 0 ? '<b style="color:limegreen;">[LIVE]</b>' : ''
- let inQueue = $('#download-' + results[i].vid).length > 0 ? '<a id="download-replay-' + results[i].vid + '" class="button icon-only" title="Download Replay"><i class="icon icon-download dim"></i></a>' : '<a id="download-replay-' + results[i].vid + '" class="button icon-only" onClick="downloadVideo(\'' + results[i].vid + '\')" title="Download Replay"><i class="icon icon-download"></i></a>'
-
- $('#list tbody').append(`
- <tr data-id="${results[i].vid}" class="user-${results[i].userid}">
- <td width="410">${results[i].title}</td>
- <td width="120" align="center">${ds}</td>
- <td width="50" align="right">${length}</td>
- <td width="70" align="right">${results[i].playnumber}</td>
- <td width="70" align="right">${results[i].likenum}</td>
- <td width="70" align="right">${results[i].sharenum}</td>
- <td width="300" style="padding: 0 16px; text-align: right;">
- <a class="button mini icon-small" onClick="copyToClipboard('${results[i].vid}')" style="font-size: 10pt;" title="Copy ID to Clipboard">ID</a>
-
- <a class="button mini icon-small" onClick="copyToClipboard('https://www.liveme.com/live.html?videoid=${results[i].vid}')" href="#" style="font-size: 10pt;" title="Copy URL to Clipboard">URL</a>
-
- <a class="button mini icon-small" onClick="copyToClipboard('${results[i].videosource || results[i].hlsvideosource}')" style="font-size: 10pt;" title="Copy Source to Clipboard (m3u8 or flv)">Source</a>
-
- <a class="button icon-only" onClick="playVideo('${results[i].vid}')" title="Watch Replay"><i class="icon icon-play"></i></a>
- <a class="button icon-only" onClick="readComments('${results[i].vid}')" title="Read Comments"><i class="icon icon-bubbles3"></i></a>
- ${inQueue}
- </td>
- </tr>
- `)
-
- $('footer h1').html($('#list tbody tr').length + ' accounts found so far, scroll down to load more.')
- }
- if (results.length === 0 && currentPage === 1) {
- $('#status').html('No videos were found searching for #' + $('#search-query').val()).show()
- } else {
- $('#status').hide()
- }
- });
-
-
-
-
- }
- function initSettingsPanel () {
- $('#authEmail').val(appSettings.get('auth.email'))
- $('#authPassword').val(appSettings.get('auth.password'))
- $('#viewmode-followers').prop('checked', appSettings.get('general.hide_zeroreplay_fans'))
- $('#viewmode-followings').prop('checked', appSettings.get('general.hide_zeroreplay_followings'))
- $('#playerpath').val(appSettings.get('general.playerpath'))
- $('#cleanup-duration').val(appSettings.get('history.viewed_maxage'))
- $('#downloads-path').val(appSettings.get('downloads.path'))
- $('#downloads-template').val(appSettings.get('downloads.template'))
- // DL Method val
- const dlMethod = appSettings.get('downloads.method') || 'ffmpeg'
- $(`input[name="downloadMethod"][value="${dlMethod}"]`).prop('checked', true)
- // DL delete tmp val
- if (appSettings.get('downloads.deltmp') === undefined) {
- appSettings.set('downloads.deltmp', true)
- }
- $('#chunk-method-tmp').prop('checked', appSettings.get('downloads.deltmp'))
- $('#downloads-parallel').val(appSettings.get('downloads.parallel') || 3)
- const ffmpegPath = appSettings.get('downloads.ffmpeg') || false
- const ffmpegQuality = appSettings.get('downloads.ffmpegquality') || false
- $('#ffmpeg-transcode-setting').val(ffmpegQuality ? ffmpegQuality : 0)
- if (ffmpegPath) { $('#ffmpegPath').val(ffmpegPath) }
- $('#lamd-enabled').prop('checked', appSettings.get('lamd.enabled'))
- $('#lamd-downloads').prop('checked', appSettings.get('lamd.handle_downloads'))
- $('#lamd-url').val(appSettings.get('lamd.url'))
- let stats = DataManager.getStats()
- $('#settings h6#version').html('Version ' + remote.app.getVersion())
- $('#counts-bookmarks').html(stats.bookmarks)
- $('#counts-profiles').html(stats.profiles)
- $('#counts-downloaded').html(stats.downloaded)
- $('#counts-watched').html(stats.watched)
- }
- function saveSettings () {
- const authEmail = $('#authEmail').val().trim()
- const authPass = $('#authPassword').val().trim()
- const savedEmail = appSettings.get('auth.email')
- const savedPass = appSettings.get('auth.password')
- // Check if inputs contain value and that the values are changed (avoid unecessary auths)
- if (authEmail && authPass && (authEmail !== savedEmail && authPass !== savedPass)) {
- appSettings.set('auth.email', authEmail)
- appSettings.set('auth.password', authPass)
- LiveMe.setAuthDetails(authEmail, authPass)
- .then(() => {
- $('#authStatus').show().find('h5').css('color', 'limegreen').html('Authentication OK!')
- })
- .catch(() => {
- $('#authStatus').show().find('h5').css('color', 'red').html('Failed to authenticate with Live.me servers. (Invalid credentials?)')
- })
- }
- appSettings.set('general.hide_zeroreplay_fans', (!!$('#viewmode-followers').is(':checked')))
- appSettings.set('general.hide_zeroreplay_followings', (!!$('#viewmode-followings').is(':checked')))
- appSettings.set('general.playerpath', $('#playerpath').val())
- appSettings.set('history.viewed_maxage', $('#cleanup-duration').val())
- appSettings.set('downloads.path', $('#downloads-path').val())
- appSettings.set('downloads.template', $('#downloads-template').val())
- appSettings.set('downloads.method', $('input[name="downloadMethod"]:checked').val() || 'ffmpeg')
- appSettings.set('downloads.deltmp', (!!$('#chunk-method-tmp').is(':checked')))
- appSettings.set('downloads.ffmpeg', $('#ffmpegPath').val().trim() || false)
- appSettings.set('downloads.parallel', $('#downloads-parallel').val() || 3)
- appSettings.set('downloads.ffmpegquality', $('#ffmpeg-transcode-setting').val())
- ipcRenderer.send('downloads-parallel', appSettings.get('downloads.parallel'))
- appSettings.set('lamd.enabled', (!!$('#lamd-enabled').is(':checked')))
- appSettings.set('lamd.handle_downloads', (!!$('#lamd-downloads').is(':checked')))
- if ($('#lamd-url').val().length < 21) $('#lamd-url').val('http://localhost:8280')
- appSettings.set('lamd.url', $('#lamd-url').val())
- }
- function resetSettings () {
- appSettings.set('general', {
- fresh_install: true,
- playerpath: '',
- hide_zeroreplay_fans: false,
- hide_zeroreplay_followings: true
- })
- appSettings.set('downloads', {
- path: path.join(app.getPath('home'), 'Downloads'),
- template: '%%replayid%%'
- })
- appSettings.set('history', {
- viewed_maxage: 1
- })
- appSettings.set('position', {
- mainWindow: [-1, -1],
- playerWindow: [-1, -1],
- bookmarksWindow: [-1, -1]
- })
- appSettings.set('size', {
- mainWindow: [1024, 600],
- playerWindow: [370, 680],
- bookmarksWindow: [400, 720]
- })
- appSettings.set('lamd', {
- enabled: false,
- url: 'http://localhost:8280',
- handle_downloads: false
- })
- DataManager.wipeAllData()
- remote.app.relaunch()
- }
- function CheckForLAMD () {
- let lamdConfig = appSettings.get('lamd')
- if (lamdConfig.enabled === false) {
- $('.lamd-button').hide()
- return
- }
- $('.lamd-button').html('<i class="icon icon-hour-glass"></i>')
- request({
- url: lamdConfig.url + '/ping',
- method: 'get'
- }, function (err, httpResponse, body) {
- if (err) return
- setTimeout(() => {
- request({
- url: lamdConfig.url + '/check-account/' + currentUser.uid,
- method: 'get',
- timeout: 2000
- }, (err, resp, body) => {
- if (err) {
- $('.lamd-button').hide()
- return
- }
- if (JSON.parse(body).message === 'Account is in the list.') {
- $('.lamd-button').html('<i class="icon icon-user-minus"></i> LAMD').attr('mode', 'remove').show()
- } else {
- $('.lamd-button').html('<i class="icon icon-user-plus"></i> LAMD').attr('mode', 'add').show()
- }
- })
- }, 100)
- })
- }
- function AddToLAMD (u) {
- let lamdConfig = appSettings.get('lamd')
- let v = $('.lamd-button').attr('mode')
- if (lamdConfig.enabled === false) return // If we are not allowed to use it, then don't continue on inside this script.
- request({
- url: lamdConfig.url + (v === 'add' ? '/add-account/' : '/remove-account/') + currentUser.uid,
- method: 'get',
- timeout: 2000
- }, function (err, httpResponse, body) {
- if (err) return
- var r = JSON.parse(body)
- if (r.message === 'Account removed.') {
- $('.lamd-button').html('<i class="icon icon-user-plus"></i> LAMD').attr('mode', 'add').show()
- $('#popup-message').html('Account removed from LAMD').animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - $('#popup-message').height() }, 400)
- } else {
- $('.lamd-button').html('<i class="icon icon-user-minus"></i> LAMD').attr('mode', 'remove').show()
- $('#popup-message').html('Account added to LAMD').animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - $('#popup-message').height() }, 400)
- }
- })
- }
- function AddReplayToLAMD (r) {
- let lamdConfig = appSettings.get('lamd')
- let v = $('.lamd-button').attr('mode')
- if (lamdConfig.enabled === false) return // If we are not allowed to use it, then don't continue on inside this script.
- request({
- url: lamdConfig.url + '/add-download/' + r,
- method: 'get',
- timeout: 2000
- }, function (err, httpResponse, body) {
- if (err) return
- $('#popup-message').html('Download added to LAMD').animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - $('#popup-message').height() }, 400)
- })
- }
|