index.js 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232
  1. /* global $ */
  2. const MAX_PER_PAGE = 5
  3. const { electron, BrowserWindow, remote, ipcRenderer, shell, dialog, clipboard } = require('electron')
  4. const fs = require('fs')
  5. const path = require('path')
  6. const appSettings = remote.require('electron-settings')
  7. const isDev = remote.getGlobal('isDev')
  8. const LiveMe = remote.getGlobal('LiveMe')
  9. const DataManager = remote.getGlobal('DataManager')
  10. const formatDuration = require('format-duration')
  11. const prettydate = require('pretty-date')
  12. const request = require('request')
  13. let currentUser = {}
  14. let currentPage = 1
  15. let currentIndex = 0
  16. let tempvar = null
  17. let hasMore = false
  18. let currentSearch = ''
  19. let scrollBusy = false
  20. let currentView = 'home'
  21. $(function () {
  22. document.title = 'LiveMe Pro Tools v' + remote.app.getVersion() // Set Title of Window
  23. setupContextMenu() // Set up the Context Menu for Cut/Copy/Paste on text fields
  24. onTypeChange() // Init Search Field
  25. setupIPCListeners() // Set up our IPC listeners
  26. setupLoadOnScroll() // Setup loading more on scroll only when searching for usernames
  27. initSettingsPanel()
  28. // Authenticate if credentials saved
  29. if (appSettings.get('auth.email') && appSettings.get('auth.password')) {
  30. LiveMe.setAuthDetails(appSettings.get('auth.email').trim(), appSettings.get('auth.password').trim())
  31. }
  32. initHome()
  33. // Store Bookmarks, History and more every 2 minutes (120,000ms) in case of a crash or something
  34. setInterval(() => {
  35. DataManager.saveToDisk()
  36. }, 120000)
  37. })
  38. function setupContextMenu () {
  39. const InputMenu = remote.Menu.buildFromTemplate([{
  40. label: 'Undo',
  41. role: 'undo'
  42. }, {
  43. label: 'Redo',
  44. role: 'redo'
  45. }, {
  46. type: 'separator'
  47. }, {
  48. label: 'Cut',
  49. role: 'cut'
  50. }, {
  51. label: 'Copy',
  52. role: 'copy'
  53. }, {
  54. label: 'Paste',
  55. role: 'paste'
  56. }, {
  57. type: 'separator'
  58. }, {
  59. label: 'Select all',
  60. role: 'selectall'
  61. }
  62. ])
  63. document.body.addEventListener('contextmenu', (e) => {
  64. e.preventDefault()
  65. e.stopPropagation()
  66. let node = e.target
  67. while (node) {
  68. if (node.nodeName.match(/^(input|textarea)$/i) || node.isContentEditable) {
  69. InputMenu.popup(remote.getCurrentWindow())
  70. break
  71. }
  72. node = node.parentNode
  73. }
  74. })
  75. }
  76. function setupLoadOnScroll () {
  77. $('main').scroll(function () {
  78. if (($(this).scrollTop() + $(this).height()) > ($('table').height() - 80)) {
  79. if (hasMore === false) return
  80. if (scrollBusy === true) return
  81. scrollBusy = true
  82. currentPage++
  83. if (currentSearch === 'performUsernameSearch') {
  84. performUsernameSearch()
  85. } else if (currentSearch === 'performHashtagSearch') {
  86. _performHashtagSearch()
  87. } else {
  88. scrollBusy = false
  89. }
  90. }
  91. })
  92. }
  93. function setupIPCListeners () {
  94. ipcRenderer.on('show-user', (event, arg) => {
  95. $('#search-query').val(arg.userid)
  96. $('#search-type').val('user-id')
  97. doSearch()
  98. })
  99. ipcRenderer.on('popup-message', (event, arg) => {
  100. let p = $('#popup-message')
  101. p.html(arg.text).animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - p.height() }, 400)
  102. })
  103. ipcRenderer.on('go-home', (event, arg) => {
  104. goHome()
  105. })
  106. ipcRenderer.on('shutdown', (event, arg) => {
  107. $('overlay').show()
  108. $('#status').html('Storing data and shutting down...')
  109. })
  110. ipcRenderer.on('download-start', (event, arg) => {
  111. if ($('#download-' + arg.videoid).length < 1) return
  112. $('#download-' + arg.videoid).addClass('active')
  113. $('#download-' + arg.videoid + ' .status').html('Starting download..')
  114. $('#download-' + arg.videoid + ' .filename').html(arg.filename)
  115. $('#download-' + arg.videoid + ' .cancel').remove()
  116. })
  117. ipcRenderer.on('download-progress', (event, arg) => {
  118. if ($('#download-' + arg.videoid).length < 1) return
  119. $('#download-' + arg.videoid + ' .status').html(arg.state)
  120. $('#download-' + arg.videoid + ' .progress-bar .bar').css('width', arg.percent + '%')
  121. })
  122. ipcRenderer.on('download-complete', (event, arg) => {
  123. if ($('#download-' + arg.videoid).length < 1) return
  124. $('#download-' + arg.videoid).remove()
  125. })
  126. ipcRenderer.on('download-error', (event, arg) => {
  127. if ($('#download-' + arg.videoid).length < 1) return
  128. $('#download-' + arg.videoid + ' .status').html('Download Error<span></span>')
  129. $('#download-' + arg.videoid).append(`<div onClick="cancelDownload('${arg.videoid}')" class="cancel">&#x2715;</div>`)
  130. })
  131. }
  132. function showMainMenu () {
  133. const MainAppMenu = remote.Menu.buildFromTemplate(
  134. [
  135. /*
  136. {
  137. label: 'Import',
  138. submenu: [
  139. {
  140. label: 'ReplayID List to Download',
  141. click: () => importReplayIDList()
  142. },
  143. {
  144. label: 'UserID List to Favorites',
  145. click: () => importUserIDList()
  146. }
  147. ]
  148. },
  149. {
  150. label: 'Export',
  151. submenu: [
  152. {
  153. label: 'Favorites List',
  154. click: () => ExportFavorites()
  155. }
  156. ]
  157. }, */
  158. {
  159. label: 'Backup/Restore',
  160. submenu: [
  161. {
  162. label: 'Backup Data',
  163. click: () => backupData()
  164. },
  165. {
  166. label: 'Restore Data',
  167. click: () => restoreData()
  168. }
  169. ]
  170. },
  171. {
  172. type: 'separator'
  173. },
  174. {
  175. label: 'Open Bookmarks',
  176. click: () => openBookmarks()
  177. },
  178. {
  179. type: 'separator'
  180. },
  181. {
  182. label: 'Help',
  183. submenu: [
  184. {
  185. label: 'NotABug Git Home',
  186. click: () => shell.openExternal('https://notabug.org/thecoder1975/liveme-pro-tools/')
  187. },
  188. {
  189. label: 'Report an Issue on Discord',
  190. click: () => shell.openExternal('https://discord.gg/vKwR3WB')
  191. }
  192. ]
  193. },
  194. {
  195. type: 'separator'
  196. },
  197. {
  198. label: 'Settings',
  199. click: () => showSettings()
  200. },
  201. {
  202. type: 'separator'
  203. },
  204. {
  205. label: 'Quit',
  206. click: () => remote.app.quit()
  207. }
  208. ]
  209. )
  210. MainAppMenu.popup(
  211. remote.getCurrentWindow(),
  212. {
  213. x: 0,
  214. y: 40
  215. }
  216. )
  217. }
  218. function onTypeChange () {
  219. let t = $('#search-type').val()
  220. switch (t) {
  221. case 'user-id':
  222. $('#search-query').attr('placeholder', 'User ID')
  223. break
  224. case 'short-id':
  225. $('#search-query').attr('placeholder', 'Short ID')
  226. break
  227. case 'video-id':
  228. $('#search-query').attr('placeholder', 'Video ID')
  229. break
  230. case 'video-url':
  231. $('#search-query').attr('placeholder', 'Video URL')
  232. break
  233. case 'hashtag':
  234. $('#search-query').attr('placeholder', 'Enter a hashtag')
  235. break
  236. case 'username-like':
  237. $('#search-query').attr('placeholder', 'Partial or Full Username')
  238. break
  239. }
  240. }
  241. function closeOverlay () {
  242. if ($('#queue-list').is(':visible')) {
  243. $('#queue-list').hide()
  244. $('overlay').hide()
  245. }
  246. }
  247. function enterOnSearch (e) { if (e.keyCode === 13) preSearch() }
  248. function copyToClipboard (i) { clipboard.writeText(i) }
  249. function showSettings () { $('#settings').show() }
  250. function hideSettings () { $('#settings').hide() }
  251. function closeWindow () { window.close() }
  252. function minimizeWindow () { remote.BrowserWindow.getFocusedWindow().minimize() }
  253. function showProgressBar () { $('#footer-progressbar').show() }
  254. function hideProgressBar () { $('#footer-progressbar').hide() }
  255. function setProgressBarValue (v) { $('#footer-progressbar div').css({ width: v + '%' }) }
  256. function showUser (u) {
  257. $('#search-type').val('user-id')
  258. $('#search-query').val(u)
  259. $('overlay').show()
  260. setTimeout(function () { preSearch() }, 500)
  261. }
  262. function openBookmarks () { ipcRenderer.send('open-bookmarks') }
  263. function showFollowing (u) { ipcRenderer.send('open-followings-window', { userid: currentUser.uid !== undefined ? currentUser.uid : u }) }
  264. function showFollowers (u) { ipcRenderer.send('open-followers-window', { userid: currentUser.uid !== undefined ? currentUser.uid : u }) }
  265. function playVideo (vid) { ipcRenderer.send('watch-replay', { videoid: vid }) }
  266. function sortReplays (name) {
  267. $('table#list tbody tr').sort(function (a, b) {
  268. var aValue = $(a).find('td[data-name="' + name + '"]').text()
  269. var bValue = $(b).find('td[data-name="' + name + '"]').text()
  270. if (name === 'date') {
  271. aValue = new Date(aValue).getTime()
  272. bValue = new Date(bValue).getTime()
  273. }
  274. return ((+aValue < +bValue) ? 1 : ((+aValue > +bValue) ? -1 : 0))
  275. }).appendTo('table#list tbody')
  276. if (hasMore) {
  277. setTimeout(() => sortReplays(name), 500)
  278. }
  279. }
  280. function downloadVideo (vid) {
  281. $('#download-replay-' + vid).html('<i class="icon icon-download dim"></i>')
  282. $('#download-replay-' + vid).unbind()
  283. if (appSettings.get('lamd.handle_downloads') === true) {
  284. AddReplayToLAMD(vid)
  285. } else {
  286. ipcRenderer.send('download-replay', { videoid: vid })
  287. if ($('#download-' + vid).length > 0) return
  288. $('#queue-list').append(`
  289. <div class="download" id="download-${vid}">
  290. <div class="filename">${vid}</div>
  291. <div class="status">Queued</div>
  292. <div class="progress-bar">
  293. <div class="bar" style="width: 0%"></div>
  294. </div>
  295. <div onClick="cancelDownload('${vid}')" class="cancel">&#x2715;</div>
  296. </div>
  297. `)
  298. }
  299. }
  300. function cancelDownload (i) {
  301. ipcRenderer.send('download-cancel', { videoid: i })
  302. $('#download-' + i).remove()
  303. }
  304. function showDownloads () {
  305. if ($('#queue-list').is(':visible')) {
  306. $('overlay').hide()
  307. $('#queue-list').hide()
  308. } else {
  309. $('overlay').show()
  310. $('#queue-list').show()
  311. }
  312. }
  313. function importReplayIDList () { ipcRenderer.send('import-queue') }
  314. function importUserIDList () { ipcRenderer.send('import-users') }
  315. function ExportFavorites () { ipcRenderer.send('export-users') }
  316. function openURL (u) { shell.openExternal(u) }
  317. function readComments (u) { ipcRenderer.send('read-comments', { userid: u }) }
  318. function goHome () {
  319. $('footer').hide()
  320. $('main').hide()
  321. $('#home').show()
  322. $('overlay').hide()
  323. $('#queue-list').hide()
  324. currentView = 'home'
  325. initHome()
  326. }
  327. function preSearch (q) {
  328. let u = $('#search-query').val()
  329. let isnum = /^\d+$/.test(u)
  330. $('overlay').hide()
  331. $('#queue-list').hide()
  332. currentView = 'search'
  333. if ((u.length === 20) && (isnum)) {
  334. if ($('#search-type').val() !== 'video-id') {
  335. $('#search-type').val('video-id')
  336. onTypeChange()
  337. }
  338. } else if ((u.length === 18) && (isnum)) {
  339. if ($('#search-type').val() !== 'user-id') {
  340. $('#search-type').val('user-id')
  341. onTypeChange()
  342. }
  343. } else if (((u.length === 8) || (u.length === 9)) && (isnum)) {
  344. if ($('#search-type').val() !== 'short-id') {
  345. $('#search-type').val('short-id')
  346. onTypeChange()
  347. }
  348. } else if (u.indexOf('http') > -1) {
  349. if ($('#search-type').val() !== 'video-url') {
  350. $('#search-type').val('video-url')
  351. onTypeChange()
  352. }
  353. } else if (u.indexOf('#') > -1) {
  354. if ($('#search-type').val() !== 'hashtag') {
  355. $('#search-type').val('hashtag')
  356. $('#search-query').val($('#search-query').val().replace('#', ''))
  357. onTypeChange()
  358. }
  359. } else if (!isnum) {
  360. if ($('#search-type').val() !== 'username-like') {
  361. $('#search-type').val('username-like')
  362. onTypeChange()
  363. }
  364. }
  365. doSearch()
  366. }
  367. function AddToBookmarks () {
  368. if (DataManager.isBookmarked(currentUser) === true) {
  369. DataManager.removeBookmark(currentUser)
  370. $('a.bookmark').attr('title', 'Add to Bookmarks').html('<i class="icon icon-star-empty"></i>')
  371. } else {
  372. DataManager.addBookmark(currentUser)
  373. $('a.bookmark').attr('title', 'Remove from Bookmarks').html('<i class="icon icon-star-full bright yellow"></i>')
  374. }
  375. }
  376. function backupData () {
  377. ipcRenderer.send('create-backup')
  378. let p = $('#popup-message')
  379. let m = 'Backup file stored in your downloads.'
  380. p.html(m).animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - p.height() - 20 }, 400)
  381. }
  382. function restoreData () {
  383. ipcRenderer.send('restore-backup')
  384. }
  385. function initHome () {
  386. $('#home div.panel').html('')
  387. // Check for updates
  388. request({
  389. url: 'https://notabug.org/thecoder1975/liveme-pro-tools/raw/master/package.json',
  390. method: 'get'
  391. }, (err, httpResponse, body) => {
  392. if (!err) {
  393. let ghversion = JSON.parse(body).version
  394. let lversion = remote.app.getVersion()
  395. let g = ghversion.split('.')
  396. let ghv = g[0] + '' + g[1]
  397. let l = lversion.split('.')
  398. let lv = l[0] + '' + l[1]
  399. let upgrade = (g[0] - l[0]) + (g[1] - l[1])
  400. if (upgrade > 0) {
  401. if ($('#home div.panel .section').length < 1) {
  402. $('#home div.panel').empty()
  403. }
  404. $('#home div.panel').append(`
  405. <div class="section">
  406. <h3><i class="icon icon-download"></i> Update Available</h3>
  407. <p>
  408. An updated release of LiveMe Pro Tools is available.
  409. </p>
  410. <button onClick="openURL('https://notabug.org/thecoder1975/liveme-pro-tools/releases/')">Download</button>
  411. </div>
  412. `)
  413. }
  414. }
  415. })
  416. $('footer h1').html('Bookmarks are now being scanned for new replays...')
  417. $('#home').show()
  418. var bookmarks = DataManager.getAllBookmarks()
  419. tempvar = {
  420. index: 0,
  421. max: bookmarks.length,
  422. list: bookmarks
  423. }
  424. $('#home #bookmarklist').empty()
  425. setTimeout(() => {
  426. _homethread()
  427. }, 50)
  428. }
  429. function _homethread () {
  430. setImmediate(() => {
  431. if (tempvar.index < tempvar.max) {
  432. setTimeout(() => _homethread(), 50)
  433. }
  434. if (tempvar.index < tempvar.max - 1) { tempvar.index++; _checkBookmark(tempvar.list[tempvar.index].uid) }
  435. if (tempvar.index < tempvar.max - 1) { tempvar.index++; _checkBookmark(tempvar.list[tempvar.index].uid) }
  436. })
  437. }
  438. function _checkBookmark (uid) {
  439. if (uid === undefined) return
  440. if (!LiveMe.user) {
  441. return setTimeout(() => _checkBookmark(), 5000)
  442. }
  443. LiveMe.getUserInfo(uid).then(user => {
  444. if (user === undefined) return
  445. let b = DataManager.getSingleBookmark(user.user_info.uid)
  446. let dt = new Date()
  447. b.counts.replays = user.count_info.video_count
  448. b.counts.friends = user.count_info.friends_count
  449. b.counts.followers = user.count_info.follower_count
  450. b.counts.followings = user.count_info.following_count
  451. b.signature = user.user_info.usign
  452. b.sex = user.user_info.sex
  453. b.face = user.user_info.face
  454. b.nickname = user.user_info.uname
  455. b.shortid = user.user_info.short_id
  456. DataManager.updateBookmark(b)
  457. if (b.counts.replays > 0) {
  458. LiveMe.getUserReplays(uid, 1, 2)
  459. .then(replays => {
  460. if (replays === undefined) return
  461. if (replays.length < 1) return
  462. let count = 0
  463. let userid = replays[0].userid
  464. let bookmark = DataManager.getSingleBookmark(userid)
  465. for (let i = 0; i < replays.length; i++) {
  466. if (replays[i].vtime - bookmark.newest_replay > 0) {
  467. let latest = prettydate.format(new Date(replays[0].vtime * 1000))
  468. let last = prettydate.format(new Date(bookmark.last_viewed * 1000))
  469. bookmark.newest_replay = Math.floor(replays[0].vtime)
  470. DataManager.updateBookmark(bookmark)
  471. if (currentView === 'home') {
  472. $('#home #bookmarklist').append(`
  473. <div class="bookmark" id="bookmark-${bookmark.uid}" onClick="showUser('${bookmark.uid}')">
  474. <img src="${bookmark.face}" class="avatar" onError="$(this).hide()">
  475. <h1>${bookmark.nickname}</h1>
  476. <h3>Newest replay posted ${latest}</h3>
  477. <h2>NEW</h2>
  478. </div>
  479. `)
  480. }
  481. break
  482. }
  483. }
  484. })
  485. .catch(error => {
  486. // Unhandled error occured
  487. })
  488. }
  489. })
  490. }
  491. function saveAccountFace () {
  492. let u = appSettings.get('downloads.path')
  493. request.get(currentUser.face)
  494. .on('error', () => { })
  495. .pipe(fs.createWriteStream(`${u}/${currentUser.uid}.jpg`))
  496. $('#popup-message').html('Image saved to downloads.').animate({ top: 40 }, 400).delay(2000).animate({ top: 0 - $('#popup-message').height() }, 400)
  497. }
  498. function doSearch () {
  499. let query = ''
  500. let userid = ''
  501. let q = $('#search-query').val()
  502. if (q.length < 1) return
  503. $('#user-details').hide()
  504. $('main').hide().removeClass('has-panel')
  505. $('#status').show().html('Performing LiveMe Search...')
  506. $('#home').hide()
  507. currentPage = 1
  508. $('#list tbody').html('')
  509. switch ($('#search-type').val()) {
  510. case 'video-url':
  511. let t = q.split('/')
  512. if (q.indexOf('/live/') > -1) {
  513. query = q[3]
  514. performVideoLookup(query)
  515. } else if (q[q.length - 1].indexof('yolo') > -1) {
  516. let a = q[q.length - 1].split('-')
  517. $('#search-query').val(a[1])
  518. $('#search-type').val('video-id')
  519. query = a[1]
  520. performVideoLookup(query)
  521. } else if (q.indexOf('videoid') > -1) {
  522. let a = t[t.length - 1].split('?')
  523. let b = a[1].split('&')
  524. for (let i = 0; i < b.length; i++) {
  525. if (b[i].indexOf('videoid') > -1) {
  526. let c = b[i].split('=')
  527. query = c[1]
  528. $('#search-query').val(c[1])
  529. $('#search-type').val('video-id')
  530. }
  531. }
  532. performVideoLookup(query)
  533. } else if (q.indexOf('userid') > -1) {
  534. let a = t[t.length - 1].split('?')
  535. let b = a[1].split('&')
  536. for (let i = 0; i < b.length; i++) {
  537. if (b[i].indexOf('userid') > -1) {
  538. let c = b[i].split('=')
  539. query = c[1]
  540. $('#search-query').val(c[1])
  541. $('#search-type').val('user-id')
  542. }
  543. }
  544. performUserLookup(query)
  545. }
  546. break
  547. case 'video-id':
  548. performVideoLookup($('#search-query').val())
  549. break
  550. case 'user-id':
  551. performUserLookup($('#search-query').val())
  552. break
  553. case 'short-id':
  554. performShortIDSearch()
  555. break
  556. case 'hashtag':
  557. $('main').show().removeClass('has-details')
  558. $('#user-details').hide()
  559. $('#list').show()
  560. $('#list thead').html('')
  561. performHashtagSearch()
  562. break
  563. case 'username-like':
  564. $('main').show().removeClass('has-details')
  565. $('#list thead').html('')
  566. performUsernameSearch()
  567. break
  568. }
  569. }
  570. function performShortIDSearch () {
  571. LiveMe.performSearch($('#search-query').val(), 1, 1, 1).then(results => {
  572. if (results.length > 0) {
  573. performUserLookup(results[0].user_id)
  574. }
  575. })
  576. }
  577. function performVideoLookup (q) {
  578. LiveMe.getVideoInfo(q)
  579. .then(video => {
  580. if (video.videosource.length < 1) {
  581. $('#status').html('Video not found or was deleted from the servers.')
  582. $('overlay').hide()
  583. $('main').hide()
  584. } else {
  585. _addReplayEntry(video, true)
  586. performUserLookup(video.userid)
  587. }
  588. }).catch(() => {
  589. $('#status').html('Video not found or was deleted from the servers.')
  590. $('overlay').hide()
  591. $('main').hide()
  592. })
  593. }
  594. function performUserLookup (uid) {
  595. LiveMe.getUserInfo(uid)
  596. .then(user => {
  597. let bookmark = DataManager.getSingleBookmark(user.user_info.uid)
  598. if (bookmark !== false) {
  599. bookmark.last_viewed = Math.floor(new Date().getTime() / 1000)
  600. DataManager.updateBookmark(bookmark)
  601. }
  602. DataManager.addViewed(user.user_info.uid)
  603. $('#list thead').html(`
  604. <tr>
  605. <th width="410">Title</th>
  606. <th width="120">
  607. <a href="#" class="link text-center" onClick="sortReplays('date')" title="Sort by Date (desc)">Date</a>
  608. </th>
  609. <th width="50" align="right">Length</th>
  610. <th width="70" align="right">
  611. <a href="#" class="link text-right" onClick="sortReplays('views')" title="Sort by Views (desc)">Views</a>
  612. </th>
  613. <th width="70" align="right">
  614. <a href="#" class="link text-right" onClick="sortReplays('likes')" title="Sort by Likes (desc)">Likes</a>
  615. </th>
  616. <th width="70" align="right">
  617. <a href="#" class="link text-right" onClick="sortReplays('shares')" title="Sort by Shares (desc)">Shares</a>
  618. </th>
  619. <th width="210">Actions</th>
  620. </tr>
  621. `)
  622. let sex = user.user_info.sex < 0 ? '' : (user.user_info.sex === 0 ? 'female' : 'male')
  623. $('#user-details').show()
  624. $('img.avatar').attr('src', user.user_info.face)
  625. $('#user-details div.info h1 span').html(user.user_info.uname)
  626. $('#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>')
  627. $('#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>')
  628. $('#user-details div.info h2.level').html('<span>Level:</span><b>' + user.user_info.level + '</b>')
  629. $('#user-details div.info h4').html(user.user_info.countryCode)
  630. if (DataManager.isBookmarked(user.user_info) === true) {
  631. $('#user-details a.bookmark').attr('title', 'Remove from Bookmarks').html('<i class="icon icon-star-full bright yellow"></i>')
  632. } else {
  633. $('#user-details a.bookmark').attr('title', 'Add to Bookmarks').html('<i class="icon icon-star-empty"></i>')
  634. }
  635. $('#user-details div.info a.following').html('Following ' + user.count_info.following_count)
  636. $('#user-details div.info a.followers').html(user.count_info.follower_count + ' Followers')
  637. setTimeout(() => {
  638. $('#status').hide()
  639. $('overlay').hide()
  640. $('main').show()
  641. }, 250)
  642. currentPage = 1
  643. currentUser = {
  644. uid: user.user_info.uid,
  645. shortid: user.user_info.short_id,
  646. signature: user.user_info.usign,
  647. sex: sex,
  648. face: user.user_info.face,
  649. nickname: user.user_info.uname,
  650. counts: {
  651. replays: user.count_info.video_count,
  652. friends: user.count_info.friends_count,
  653. followers: user.count_info.follower_count,
  654. followings: user.count_info.following_count
  655. },
  656. last_viewed: Math.floor((new Date()).getTime() / 1000),
  657. newest_replay: 0
  658. }
  659. getUsersReplays()
  660. showProgressBar()
  661. })
  662. .catch(() => {
  663. $('#status').html('Account no longer available.')
  664. })
  665. }
  666. function getUsersReplays () {
  667. if (!LiveMe.user) {
  668. $('#replay-result-alert').html('<span>Error!</span> You are not authenticated, please enter your login details under Settings.').fadeIn(200)
  669. return setTimeout(() => getUsersReplays(), 5000)
  670. } else {
  671. $('#replay-result-alert').hide()
  672. }
  673. LiveMe.getUserReplays(currentUser.uid, currentPage, MAX_PER_PAGE)
  674. .then(replays => {
  675. if ((typeof replays === 'undefined') || (replays == null)) {
  676. if (currentPage === 1) {
  677. $('#replay-result-alert').html('<span>No replays!</span> There is no publicly listed replays available.').fadeIn(200)
  678. $('footer h1').html('No publicly listed replays available.')
  679. hideProgressBar()
  680. }
  681. return
  682. }
  683. if (replays.length > 0) {
  684. if (replays[0].uid === currentUser.userid) {
  685. for (let i = 0; i < replays.length; i++) {
  686. _addReplayEntry(replays[i], false)
  687. }
  688. }
  689. }
  690. $('#list tbody tr').not('.user-' + currentUser.uid).remove()
  691. $('footer h1').html($('#list tbody tr').length + ' visible of ' + currentUser.counts.replays + ' total replays loaded.')
  692. setProgressBarValue(($('#list tbody tr').length / currentUser.counts.replays) * 100)
  693. hasMore = replays.length === MAX_PER_PAGE
  694. currentSearch = 'getUsersReplays'
  695. if (hasMore === true) {
  696. setTimeout(() => {
  697. currentPage++
  698. getUsersReplays()
  699. }, 500)
  700. } else {
  701. let c = $('#list tbody tr td.highlight').length
  702. let d = $('#list tbody tr').length
  703. if (c.length === 0) {
  704. $('#list table tbody tr.unlisted').removeClass('unlisted')
  705. } else {
  706. $('#list table tbody tr.unlisted').remove()
  707. $('footer h1').html($('#list tbody tr').length + ' visible of ' + currentUser.counts.replays + ' total replays loaded.')
  708. }
  709. if (d === 0) $('footer h1').html('No publicly listed replays available.')
  710. hideProgressBar()
  711. }
  712. })
  713. .catch(error => {
  714. // Unhandled error
  715. })
  716. }
  717. function _addReplayEntry (replay, wasSearched) {
  718. if (replay.userid !== currentUser.uid) return
  719. if (replay.vtime > currentUser.newest_replay) currentUser.newest_replay = replay.vtime
  720. let dt = new Date(replay.vtime * 1000)
  721. let ds = (dt.getMonth() + 1) + '-' + dt.getDate() + '-' + dt.getFullYear() + ' ' + (dt.getHours() < 10 ? '0' : '') + dt.getHours() + ':' + (dt.getMinutes() < 10 ? '0' : '') + dt.getMinutes()
  722. let highlight = $('#search-type').val() === 'video-id' ? ($('#search-query').val() === replay.vid ? 'highlight' : '') : ''
  723. let length = formatDuration(parseInt(replay.videolength) * 1000)
  724. let searched = wasSearched ? 'unlisted' : ''
  725. let unlisted = searched ? '[UNLISTED]' : ''
  726. let downloadDate = DataManager.wasDownloaded(replay.vid)
  727. let watchDate = DataManager.wasWatched(replay.vid)
  728. 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>'
  729. 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>'
  730. let seen = watchDate === false ? '' : 'watched'
  731. let isLive = replay.hlsvideosource.endsWith('flv') || replay.hlsvideosource.indexOf('liveplay') > 0 ? '<b style="color:limegreen;">[LIVE]</b>' : ''
  732. 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>'
  733. const template = Handlebars.compile($('#replays-list-row').html())
  734. const html = template(
  735. Object.assign(replay, {
  736. searched,
  737. seen,
  738. highlight,
  739. watched,
  740. downloaded,
  741. unlisted,
  742. isLive,
  743. length,
  744. ds,
  745. inQueue,
  746. source: replay.videosource || replay.hlsvideosource
  747. })
  748. )
  749. /*
  750. let h = `
  751. <tr data-id="${replay.vid}" class="${searched} ${seen} user-${replay.userid}">
  752. <td width="410" class="${highlight}">${watched}&nbsp;&nbsp;${downloaded}&nbsp;&nbsp;&nbsp;${unlisted}${isLive}${replay.title}</td>
  753. <td width="120" class="${highlight}" align="center">${ds}</td>
  754. <td width="50" class="${highlight}" align="right">${length}</td>
  755. <td width="70" class="${highlight}" align="right">${replay.playnumber}</td>
  756. <td width="70" class="${highlight}" align="right">${replay.likenum}</td>
  757. <td width="70" class="${highlight}" align="right">${replay.sharenum}</td>
  758. <td width="300" class="${highlight}" style="padding: 0 16px; text-align: right;">
  759. <a class="button mini icon-small" onClick="copyToClipboard('${replay.vid}')" style="font-size: 10pt;" title="Copy ID to Clipboard">ID</a>
  760. &nbsp;
  761. <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>
  762. &nbsp;
  763. <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>
  764. &nbsp;&nbsp;&nbsp;
  765. <a class="button icon-only" onClick="playVideo('${replay.vid}')" title="Watch Replay"><i class="icon icon-play"></i></a>&nbsp;&nbsp;
  766. <a class="button icon-only" onClick="readComments('${replay.vid}')" title="Read Comments"><i class="icon icon-bubbles3"></i></a>&nbsp;&nbsp;
  767. ${inQueue}
  768. </td>
  769. </tr>
  770. `
  771. */
  772. const item = $(html).hide().fadeIn(200)
  773. $('#list tbody').append(item)
  774. }
  775. function performUsernameSearch () {
  776. LiveMe.performSearch($('#search-query').val(), currentPage, MAX_PER_PAGE, 1)
  777. .then(results => {
  778. currentSearch = 'performUsernameSearch'
  779. hasMore = results.length >= MAX_PER_PAGE
  780. setTimeout(function () { scrollBusy = false }, 250)
  781. for (var i = 0; i < results.length; i++) {
  782. 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>'
  783. let viewed = DataManager.wasProfileViewed(results[i].user_id)
  784. ? '<i class="icon icon-eye bright blue" title="Last viewed ' + prettydate.format(DataManager.wasProfileViewed(results[i].user_id)) + '"></i>'
  785. : '<i class="icon icon-eye dim"></i>'
  786. var sex = results[i].sex < 0 ? '' : (results[i].sex == 0 ? 'female' : 'male');
  787. $('#list tbody').append(`
  788. <tr id="user-${results[i].user_id}" class="user-search ${sex}">
  789. <td width="128" style="text-align: center;">
  790. <img src="${results[i].face}" style="height: 128px; width: 128px;" onError="$(this).hide()">
  791. </td>
  792. <td width="896" class="details">
  793. <h4>${results[i].nickname}</h4>
  794. <h5 class="userid"></h5>
  795. <h5 class="shortid"></h5>
  796. <h5 class="level"></h5>
  797. <h5 class="country"></h5>
  798. <div class="bookmarked">${bookmarked}</div>
  799. <div class="viewed">${viewed}</div>
  800. <a class="button replays" onClick="showUser('${results[i].user_id}')">0 Replays</a>
  801. <a class="button followings" onClick="showFollowing('${results[i].user_id}')">Following 0</a>
  802. <a class="button followers" onClick="showFollowers('${results[i].user_id}')">0 Fans</a>
  803. </td>
  804. </tr>
  805. `)
  806. LiveMe.getUserInfo(results[i].user_id)
  807. .then(user => {
  808. if (user === undefined) return
  809. if (user === null) return
  810. $('#user-' + user.user_info.uid + ' td.details a.replays').html(`${user.count_info.video_count} Replays`)
  811. $('#user-' + user.user_info.uid + ' td.details a.followings').html(`Following ${user.count_info.following_count}`)
  812. $('#user-' + user.user_info.uid + ' td.details a.followers').html(`${user.count_info.follower_count} Fans`)
  813. $('#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>`)
  814. $('#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>`)
  815. $('#user-' + user.user_info.uid + ' td.details h5.level').html(`Level: <span>${user.user_info.level}</span>`)
  816. $('#user-' + user.user_info.uid + ' td.details h5.country').html(`${user.user_info.countryCode}`)
  817. })
  818. $('footer h1').html($('#list tbody tr').length + ' accounts found so far, scroll down to load more.')
  819. }
  820. if (results.length === 0 && currentPage === 1) {
  821. $('#status').html('No users were found searching for ' + $('#search-query').val()).show()
  822. } else {
  823. $('#status').hide()
  824. }
  825. })
  826. }
  827. function performHashtagSearch() {
  828. $('#list thead').html(`
  829. <tr>
  830. <th width="410">Title</th>
  831. <th width="120">
  832. <a href="#" class="link text-center" onClick="sortReplays('date')" title="Sort by Date (desc)">Date</a>
  833. </th>
  834. <th width="50" align="right">Length</th>
  835. <th width="70" align="right">
  836. <a href="#" class="link text-right" onClick="sortReplays('views')" title="Sort by Views (desc)">Views</a>
  837. </th>
  838. <th width="70" align="right">
  839. <a href="#" class="link text-right" onClick="sortReplays('likes')" title="Sort by Likes (desc)">Likes</a>
  840. </th>
  841. <th width="70" align="right">
  842. <a href="#" class="link text-right" onClick="sortReplays('shares')" title="Sort by Shares (desc)">Shares</a>
  843. </th>
  844. <th width="210">Actions</th>
  845. </tr>
  846. `)
  847. setTimeout(() => {
  848. _performHashtagSearch()
  849. }, 100);
  850. }
  851. function _performHashtagSearch() {
  852. LiveMe.performSearch($('#search-query').val(), currentPage, MAX_PER_PAGE, 2)
  853. .then(results => {
  854. currentSearch = 'performHashtagSearch'
  855. hasMore = results.length >= MAX_PER_PAGE
  856. setTimeout(function () { scrollBusy = false }, 250)
  857. for (var i = 0; i < results.length; i++) {
  858. let dt = new Date(results[i].vtime * 1000)
  859. let ds = (dt.getMonth() + 1) + '-' + dt.getDate() + '-' + dt.getFullYear() + ' ' + (dt.getHours() < 10 ? '0' : '') + dt.getHours() + ':' + (dt.getMinutes() < 10 ? '0' : '') + dt.getMinutes()
  860. let length = formatDuration(parseInt(results[i].videolength) * 1000)
  861. let downloadDate = DataManager.wasDownloaded(results[i].vid)
  862. let watchDate = DataManager.wasWatched(results[i].vid)
  863. 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>'
  864. 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>'
  865. let seen = watchDate === false ? '' : 'watched'
  866. let isLive = results[i].hlsvideosource.endsWith('flv') || results[i].hlsvideosource.indexOf('liveplay') > 0 ? '<b style="color:limegreen;">[LIVE]</b>' : ''
  867. 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>'
  868. $('#list tbody').append(`
  869. <tr data-id="${results[i].vid}" class="user-${results[i].userid}">
  870. <td width="410">${results[i].title}</td>
  871. <td width="120" align="center">${ds}</td>
  872. <td width="50" align="right">${length}</td>
  873. <td width="70" align="right">${results[i].playnumber}</td>
  874. <td width="70" align="right">${results[i].likenum}</td>
  875. <td width="70" align="right">${results[i].sharenum}</td>
  876. <td width="300" style="padding: 0 16px; text-align: right;">
  877. <a class="button mini icon-small" onClick="copyToClipboard('${results[i].vid}')" style="font-size: 10pt;" title="Copy ID to Clipboard">ID</a>
  878. &nbsp;
  879. <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>
  880. &nbsp;
  881. <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>
  882. &nbsp;&nbsp;&nbsp;
  883. <a class="button icon-only" onClick="playVideo('${results[i].vid}')" title="Watch Replay"><i class="icon icon-play"></i></a>&nbsp;&nbsp;
  884. <a class="button icon-only" onClick="readComments('${results[i].vid}')" title="Read Comments"><i class="icon icon-bubbles3"></i></a>&nbsp;&nbsp;
  885. ${inQueue}
  886. </td>
  887. </tr>
  888. `)
  889. $('footer h1').html($('#list tbody tr').length + ' accounts found so far, scroll down to load more.')
  890. }
  891. if (results.length === 0 && currentPage === 1) {
  892. $('#status').html('No videos were found searching for #' + $('#search-query').val()).show()
  893. } else {
  894. $('#status').hide()
  895. }
  896. });
  897. }
  898. function initSettingsPanel () {
  899. $('#authEmail').val(appSettings.get('auth.email'))
  900. $('#authPassword').val(appSettings.get('auth.password'))
  901. $('#viewmode-followers').prop('checked', appSettings.get('general.hide_zeroreplay_fans'))
  902. $('#viewmode-followings').prop('checked', appSettings.get('general.hide_zeroreplay_followings'))
  903. $('#playerpath').val(appSettings.get('general.playerpath'))
  904. $('#cleanup-duration').val(appSettings.get('history.viewed_maxage'))
  905. $('#downloads-path').val(appSettings.get('downloads.path'))
  906. $('#downloads-template').val(appSettings.get('downloads.template'))
  907. // DL Method val
  908. const dlMethod = appSettings.get('downloads.method') || 'ffmpeg'
  909. $(`input[name="downloadMethod"][value="${dlMethod}"]`).prop('checked', true)
  910. // DL delete tmp val
  911. if (appSettings.get('downloads.deltmp') === undefined) {
  912. appSettings.set('downloads.deltmp', true)
  913. }
  914. $('#chunk-method-tmp').prop('checked', appSettings.get('downloads.deltmp'))
  915. $('#downloads-parallel').val(appSettings.get('downloads.parallel') || 3)
  916. const ffmpegPath = appSettings.get('downloads.ffmpeg') || false
  917. const ffmpegQuality = appSettings.get('downloads.ffmpegquality') || false
  918. $('#ffmpeg-transcode-setting').val(ffmpegQuality ? ffmpegQuality : 0)
  919. if (ffmpegPath) { $('#ffmpegPath').val(ffmpegPath) }
  920. $('#lamd-enabled').prop('checked', appSettings.get('lamd.enabled'))
  921. $('#lamd-downloads').prop('checked', appSettings.get('lamd.handle_downloads'))
  922. $('#lamd-url').val(appSettings.get('lamd.url'))
  923. let stats = DataManager.getStats()
  924. $('#settings h6#version').html('Version ' + remote.app.getVersion())
  925. $('#counts-bookmarks').html(stats.bookmarks)
  926. $('#counts-profiles').html(stats.profiles)
  927. $('#counts-downloaded').html(stats.downloaded)
  928. $('#counts-watched').html(stats.watched)
  929. }
  930. function saveSettings () {
  931. const authEmail = $('#authEmail').val().trim()
  932. const authPass = $('#authPassword').val().trim()
  933. const savedEmail = appSettings.get('auth.email')
  934. const savedPass = appSettings.get('auth.password')
  935. // Check if inputs contain value and that the values are changed (avoid unecessary auths)
  936. if (authEmail && authPass && (authEmail !== savedEmail && authPass !== savedPass)) {
  937. appSettings.set('auth.email', authEmail)
  938. appSettings.set('auth.password', authPass)
  939. LiveMe.setAuthDetails(authEmail, authPass)
  940. .then(() => {
  941. $('#authStatus').show().find('h5').css('color', 'limegreen').html('Authentication OK!')
  942. })
  943. .catch(() => {
  944. $('#authStatus').show().find('h5').css('color', 'red').html('Failed to authenticate with Live.me servers. (Invalid credentials?)')
  945. })
  946. }
  947. appSettings.set('general.hide_zeroreplay_fans', (!!$('#viewmode-followers').is(':checked')))
  948. appSettings.set('general.hide_zeroreplay_followings', (!!$('#viewmode-followings').is(':checked')))
  949. appSettings.set('general.playerpath', $('#playerpath').val())
  950. appSettings.set('history.viewed_maxage', $('#cleanup-duration').val())
  951. appSettings.set('downloads.path', $('#downloads-path').val())
  952. appSettings.set('downloads.template', $('#downloads-template').val())
  953. appSettings.set('downloads.method', $('input[name="downloadMethod"]:checked').val() || 'ffmpeg')
  954. appSettings.set('downloads.deltmp', (!!$('#chunk-method-tmp').is(':checked')))
  955. appSettings.set('downloads.ffmpeg', $('#ffmpegPath').val().trim() || false)
  956. appSettings.set('downloads.parallel', $('#downloads-parallel').val() || 3)
  957. appSettings.set('downloads.ffmpegquality', $('#ffmpeg-transcode-setting').val())
  958. ipcRenderer.send('downloads-parallel', appSettings.get('downloads.parallel'))
  959. appSettings.set('lamd.enabled', (!!$('#lamd-enabled').is(':checked')))
  960. appSettings.set('lamd.handle_downloads', (!!$('#lamd-downloads').is(':checked')))
  961. if ($('#lamd-url').val().length < 21) $('#lamd-url').val('http://localhost:8280')
  962. appSettings.set('lamd.url', $('#lamd-url').val())
  963. }
  964. function resetSettings () {
  965. appSettings.set('general', {
  966. fresh_install: true,
  967. playerpath: '',
  968. hide_zeroreplay_fans: false,
  969. hide_zeroreplay_followings: true
  970. })
  971. appSettings.set('downloads', {
  972. path: path.join(app.getPath('home'), 'Downloads'),
  973. template: '%%replayid%%'
  974. })
  975. appSettings.set('history', {
  976. viewed_maxage: 1
  977. })
  978. appSettings.set('position', {
  979. mainWindow: [-1, -1],
  980. playerWindow: [-1, -1],
  981. bookmarksWindow: [-1, -1]
  982. })
  983. appSettings.set('size', {
  984. mainWindow: [1024, 600],
  985. playerWindow: [370, 680],
  986. bookmarksWindow: [400, 720]
  987. })
  988. appSettings.set('lamd', {
  989. enabled: false,
  990. url: 'http://localhost:8280',
  991. handle_downloads: false
  992. })
  993. DataManager.wipeAllData()
  994. remote.app.relaunch()
  995. }
  996. function CheckForLAMD () {
  997. let lamdConfig = appSettings.get('lamd')
  998. if (lamdConfig.enabled === false) {
  999. $('.lamd-button').hide()
  1000. return
  1001. }
  1002. $('.lamd-button').html('<i class="icon icon-hour-glass"></i>')
  1003. request({
  1004. url: lamdConfig.url + '/ping',
  1005. method: 'get'
  1006. }, function (err, httpResponse, body) {
  1007. if (err) return
  1008. setTimeout(() => {
  1009. request({
  1010. url: lamdConfig.url + '/check-account/' + currentUser.uid,
  1011. method: 'get',
  1012. timeout: 2000
  1013. }, (err, resp, body) => {
  1014. if (err) {
  1015. $('.lamd-button').hide()
  1016. return
  1017. }
  1018. if (JSON.parse(body).message === 'Account is in the list.') {
  1019. $('.lamd-button').html('<i class="icon icon-user-minus"></i> LAMD').attr('mode', 'remove').show()
  1020. } else {
  1021. $('.lamd-button').html('<i class="icon icon-user-plus"></i> LAMD').attr('mode', 'add').show()
  1022. }
  1023. })
  1024. }, 100)
  1025. })
  1026. }
  1027. function AddToLAMD (u) {
  1028. let lamdConfig = appSettings.get('lamd')
  1029. let v = $('.lamd-button').attr('mode')
  1030. if (lamdConfig.enabled === false) return // If we are not allowed to use it, then don't continue on inside this script.
  1031. request({
  1032. url: lamdConfig.url + (v === 'add' ? '/add-account/' : '/remove-account/') + currentUser.uid,
  1033. method: 'get',
  1034. timeout: 2000
  1035. }, function (err, httpResponse, body) {
  1036. if (err) return
  1037. var r = JSON.parse(body)
  1038. if (r.message === 'Account removed.') {
  1039. $('.lamd-button').html('<i class="icon icon-user-plus"></i> LAMD').attr('mode', 'add').show()
  1040. $('#popup-message').html('Account removed from LAMD').animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - $('#popup-message').height() }, 400)
  1041. } else {
  1042. $('.lamd-button').html('<i class="icon icon-user-minus"></i> LAMD').attr('mode', 'remove').show()
  1043. $('#popup-message').html('Account added to LAMD').animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - $('#popup-message').height() }, 400)
  1044. }
  1045. })
  1046. }
  1047. function AddReplayToLAMD (r) {
  1048. let lamdConfig = appSettings.get('lamd')
  1049. let v = $('.lamd-button').attr('mode')
  1050. if (lamdConfig.enabled === false) return // If we are not allowed to use it, then don't continue on inside this script.
  1051. request({
  1052. url: lamdConfig.url + '/add-download/' + r,
  1053. method: 'get',
  1054. timeout: 2000
  1055. }, function (err, httpResponse, body) {
  1056. if (err) return
  1057. $('#popup-message').html('Download added to LAMD').animate({ top: 40 }, 400).delay(3000).animate({ top: 0 - $('#popup-message').height() }, 400)
  1058. })
  1059. }