Skip to content

Commit

Permalink
feat(core): open files on Mac (it does not use argv)
Browse files Browse the repository at this point in the history
fix(core): can not re-open dockerise window (Mac only)
  • Loading branch information
feugy committed Oct 18, 2020
1 parent 1ce2494 commit 424cb88
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 41 deletions.
63 changes: 40 additions & 23 deletions main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

const { config } = require('dotenv')
const { join } = require('path')
const { platform } = require('os')
const electron = require('electron')
const shortcut = require('electron-localshortcut')
const { autoUpdater } = require('electron-updater')
const { ReplaySubject } = require('rxjs')
const { bufferWhen, debounceTime, filter } = require('rxjs/operators')
const models = require('./models')
const { tracks, media, settings, playlists } = require('./services')
const {
Expand All @@ -26,19 +29,27 @@ exports.main = async argv => {
let unsubscribe

const logger = getLogger()

if (!app.isPackaged) {
// when package, argv does not include the usual "node" first parameter
argv.shift()
// Because macOS use events for opened files, and even before the app is ready, we need to buffer them to open them at once
const openFiles$ = new ReplaySubject()

if (platform() === 'darwin') {
// on macOS, open files will be passed with events
app.on('open-file', (evt, entry) => openFiles$.next(entry))
} else {
if (!app.isPackaged) {
// when package, argv does not include the usual "node" first parameter
argv.shift()
}
// other OS will pass opened files/folders as arguments
for (const entry of argv.slice(1)) {
openFiles$.next(entry)
}
}
// list of all files/folders from the OS
const fileEntries = argv.slice(1)

logger.info(
{
levelFile: process.env.LOG_LEVEL_FILE || '.levels',
pid: process.pid,
fileEntries
pid: process.pid
},
`starting... To change log levels, edit the level file and run \`kill -USR2 ${process.pid}\``
)
Expand Down Expand Up @@ -96,7 +107,7 @@ exports.main = async argv => {
registerRenderer(win)
configureExternalLinks(win)

unsubscribe = subscribeRemote({
const unsubscribeRemote = subscribeRemote({
core: {
focusWindow: () => focusOnNotification(win),
getVersions: () => ({
Expand All @@ -110,23 +121,31 @@ exports.main = async argv => {
media,
...electron
})

win.once('ready-to-show', () => win.show())
await win.loadURL(`file://${join(publicFolder, 'index.html')}`)
}
const openSubscription = openFiles$
.pipe(
bufferWhen(() => openFiles$.pipe(debounceTime(200))),
filter(entries => entries.length > 0)
)
.subscribe(fileEntries => {
logger.info({ fileEntries }, `opening files`)
// add relevant files to track queue
tracks.play(fileEntries)
})

// Quit when all windows are closed, except on macOS.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
unsubscribe()
unsubscribe = () => {
unsubscribeRemote()
openSubscription.unsubscribe()
}
})
}

app.on('activate', () => {
// macOS dock support
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
// Quit when all windows are closed
app.on('window-all-closed', () => {
// TODO on macOS, we should let the music play
app.quit()
unsubscribe()
})

await models.init(getStoragePath('db.sqlite3'))
Expand All @@ -135,8 +154,6 @@ exports.main = async argv => {

await app.whenReady()
await createWindow()
// add relevant files to track queue
tracks.play(fileEntries)

// autoUpdater is using logger functions detached from their instance
const updaterLogger = getLogger('updater')
Expand Down
79 changes: 62 additions & 17 deletions main/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

const { EventEmitter } = require('events')
const { resolve } = require('path')
const os = require('os')
const electron = require('electron')
const { autoUpdater } = require('electron-updater')
const faker = require('faker')
const { main } = require('.')
const models = require('./models')
const services = require('./services')
const { configureExternalLinks } = require('./utils')
const { sleep } = require('./tests')

let platformSpy = jest.spyOn(os, 'platform')
const { main } = require('.')
const { app } = require('electron')

jest.mock('electron', () => {
const { EventEmitter } = require('events')
Expand Down Expand Up @@ -45,30 +50,34 @@ describe('Application test', () => {
let win

beforeEach(() => {
jest.resetModules()
jest.clearAllMocks()
win = new EventEmitter()
win.loadURL = jest.fn()
electron.BrowserWindow.mockReturnValue(win)
electron.app.removeAllListeners()
})

afterEach(() => {
app.emit('window-all-closed')
})

it('initialize models, tracks service and loads renderer', async () => {
await main(['asar-location'])

expect(models.init).toHaveBeenCalledWith('db.sqlite3')
expect(models.init).toHaveBeenCalledTimes(1)
expect(services.settings.init).toHaveBeenCalledTimes(1)
expect(services.tracks.listen).toHaveBeenCalledTimes(1)
expect(services.tracks.play).toHaveBeenCalledWith([])
expect(services.tracks.play).toHaveBeenCalledTimes(1)
expect(win.loadURL).toHaveBeenCalledWith(
`file://${resolve(__dirname, '..', 'public')}/index.html`
)
expect(electron.app.quit).not.toHaveBeenCalled()
expect(configureExternalLinks).toHaveBeenCalledWith(win)
expect(configureExternalLinks).toHaveBeenCalledTimes(1)
expect(autoUpdater.checkForUpdatesAndNotify).toHaveBeenCalledTimes(1)

await sleep(300)
expect(services.tracks.play).not.toHaveBeenCalled()
})

it('quits when closing window', async () => {
Expand All @@ -78,22 +87,58 @@ describe('Application test', () => {
expect(electron.app.quit).toHaveBeenCalledTimes(1)
})

describe('given some parameters from CLI', () => {
const file1 = faker.system.filePath()
const file2 = faker.system.filePath()
describe('given some files to open', () => {
const files = []

beforeEach(() => {
files.splice(
0,
files.length,
faker.system.filePath(),
faker.system.filePath()
)
})

describe('given a linux or windows machine', () => {
beforeAll(() => {
platformSpy.mockImplementation(() => 'linux')
})

it('plays them when packed', async () => {
electron.app.isPackaged = true
await main(['asar-location', ...files])

await sleep(300)
expect(services.tracks.play).toHaveBeenCalledWith(files)
expect(services.tracks.play).toHaveBeenCalledTimes(1)
})

it('tries to plays them when packed', async () => {
electron.app.isPackaged = true
await main(['asar-location', file1, file2])
expect(services.tracks.play).toHaveBeenCalledWith([file1, file2])
expect(services.tracks.play).toHaveBeenCalledTimes(1)
it('plays them when unpacked', async () => {
electron.app.isPackaged = false
await main(['electron', '.', ...files])

await sleep(300)
expect(services.tracks.play).toHaveBeenCalledWith(files)
expect(services.tracks.play).toHaveBeenCalledTimes(1)
})
})

it('tries to plays them when unpacked', async () => {
electron.app.isPackaged = false
await main(['electron', '.', file1, file2])
expect(services.tracks.play).toHaveBeenCalledWith([file1, file2])
expect(services.tracks.play).toHaveBeenCalledTimes(1)
describe('given an OSX machine', () => {
beforeAll(() => {
platformSpy.mockImplementation(() => 'darwin')
})

it('plays them', async () => {
const promise = main(['asar-location', ...files])
for (const file of files) {
app.emit('open-file', {}, file)
}
await promise

await sleep(300)
expect(services.tracks.play).toHaveBeenCalledWith(files)
expect(services.tracks.play).toHaveBeenCalledTimes(1)
})
})
})
})
5 changes: 4 additions & 1 deletion main/providers/local/cover-finder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ describe('Cover finder', () => {
it('finds capitalized', async () => {
const jpeg = join(path, 'Cover.jpeg')
await fs.ensureFile(jpeg)
expect(await findInFolder(join(path, 'file.mp3'))).toEqual(jpeg)

expect(await findInFolder(join(path, 'file.mp3'))).toEqual(
join(path, `${os.platform() === 'linux' ? 'Cover' : 'cover'}.jpeg`)
)
})

describe('given cover.jpg', () => {
Expand Down

0 comments on commit 424cb88

Please # to comment.