Skip to content

Commit

Permalink
Proper build, cleaned up UI for selecting devices, better error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
dado3212 committed Jun 21, 2024
1 parent 1025d7f commit 29580d2
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 87 deletions.
58 changes: 54 additions & 4 deletions css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,47 @@ body {
height: 100vh;
}

.devices {
display: flex;
align-items: center;

span {
font-size: 0.9em;
}

.device {
border: none;
background-color: rgba(0, 0, 0, 0.04);
padding: 5px 10px;
border-radius: 4px;
margin: 0 5px;
cursor: pointer;

transition: all 0.3s ease;

i {
margin-right: 5px;
}

&:hover {
background-color: rgba(0, 0, 0, 0.09);
}
}
}

#refresh {
border: none;
background-color: transparent;
font-size: 1.1em;
font-family: 'SF Pro', -apple-system, system-ui, sans-serif;
cursor: pointer;
color: #272727;

&:disabled {
cursor: none;
}
}

#content {
display: flex;
height: calc(100% - 51px);
Expand Down Expand Up @@ -140,7 +181,10 @@ body {
cursor: pointer;
user-select: none;

color: #666666;

border-radius: 3px;
padding: 6px 4px;

transition: all 0.4s ease;

Expand All @@ -152,15 +196,11 @@ body {
#back {
top: 1px;
right: 30px;
padding: 8px 4px 3px 4px;
}

#forward {
transform: rotate(180deg);
display: inline-block;
right: 10px;
top: 1px;
padding: 9px 3px 2px 4px;
}

.progress {
Expand All @@ -176,6 +216,16 @@ body {
}
}

#no-results {
text-align: center;
margin-top: 20px;
color: #272727;

&.hidden {
display: none;
}
}

@font-face {
font-family: 'SF Pro';
font-style: normal;
Expand Down
16 changes: 10 additions & 6 deletions html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,26 @@
<meta charset="UTF-8">
<title>Books Annotations</title>
<link href="../css/main.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
</head>
<body>
<div id="menu">
<div id="devices">
<span>Select Device...</span>
<button id="refresh">Refresh</button>
<div class="devices">
<span>Loading...</span>
<div id="devices"></div>
<button id="refresh" title="Refresh"><i class="fas fa-arrows-rotate"></i></button>
</div>
<div class="search">
<input type="text" id="search" placeholder="Search...">
<span class="progress hidden">1/130</span>
<span id="back" class="hidden"></span>
<span id="forward" class="hidden"></span>
<span id="back" class="hidden"><i class="fas fa-angle-up"></i></span>
<span id="forward" class="hidden"><i class="fas fa-angle-down"></i></span>
</div>
</div>
<div id="content">
<div class="books"></div>
<div class="books">
<div id="no-results" class="hidden">No books with annotations.</div>
</div>
<div class="annotations">
</div>
</div>
Expand Down
122 changes: 53 additions & 69 deletions js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,10 @@ const libijs = require('../libijs');
const meaco = require("meaco");

var deviceManager = null;
var device = null;
var deviceName = null;
var mainWindow;

function testPair(device) {
return meaco(function* doTestAfc() {
console.log(device);
const lockdownClient = yield libijs.lockdownd.getClient(device);

const pairRecord = yield lockdownClient.__usbmuxdClient.readPairRecord(device.udid);
console.log(pairRecord)

// TODO: figure out a better way to detect if paired
const afc = yield libijs.services.getService(device, "afc", lockdownClient);

if (!afc) {
console.log('not paired?');
// do the pairing thing
const response = yield lockdownClient.pair();
console.log(response);
return false;
}
var isDeviceManagerReady = false;
var onDeviceManagerReady = () => { };

return true;
});
//const afc = yield libijs.services.getService(device, "afc");
}

function runPair(device) {
testPair(device)
.error((e) => {
console.error('Error:', e);
process.exit(1);
})
.catch((e) => {
console.error('Caught:', e);
process.exit(1);
})
.done((result) => {
console.log('Result:', result);
});
}
var mainWindow;

const createWindow = () => {
mainWindow = new BrowserWindow({
Expand All @@ -61,55 +23,77 @@ const createWindow = () => {

mainWindow.loadFile('html/index.html');

mainWindow.webContents.on('found-in-page', (event, result) => {
// Forward found-in-page for the 1/x UI appearance
mainWindow.webContents.on('found-in-page', (_, result) => {
mainWindow.send('found-in-page', result);
});

// Save the device manager
deviceManager = libijs.createClient().deviceManager;
deviceManager.ready(() => {
device = deviceManager.getDevice();

libijs.services.getService(device, "afc").done(afcClient => {
return meaco(function* doAfcExample() {
const lockdownClient = yield libijs.lockdownd.getClient(device);
const deviceInfo = yield lockdownClient.getValue(null, null);
deviceName = deviceInfo['DeviceName'];
});
});
isDeviceManagerReady = true;
onDeviceManagerReady();
});
};

app.whenReady().then(createWindow);

ipcMain.handle('read-plist', async (event, filePath, name) => {
let device = deviceManager.getDevice();

libijs.services.getService(device, "afc").done(afcClient => {
return meaco(function* doAfcExample() {
event.sender.send('plist-data', {
file: name,
data: (yield afcClient.readFile(filePath)).toString(),
});
const file = yield afcClient.readFile(filePath);
if (file == null) {
event.sender.send('plist-data', {
file: name,
data: null,
});
} else {
event.sender.send('plist-data', {
file: name,
data: file.toString(),
});
}
});
}).error((e) => {
console.error('Error:', e);
}).catch((e) => {
event.sender.send('error', 'Please unlock and trust this device.' );
});
});

ipcMain.handle('get-device-name', async (event) => {
if (deviceName !== null) {
event.sender.send('device-name', deviceName);
function sendDevice(event) {
let device = deviceManager.getDevice();
if (device == null) {
event.sender.send('device-name', { success: false, message: 'No device found. Please attach device.' });
return;
}
device = deviceManager.getDevice();
if (device === null) {
event.sender.send('device-name', null);
}

libijs.services.getService(device, "afc").done(afcClient => {
return meaco(function* doAfcExample() {
const lockdownClient = yield libijs.lockdownd.getClient(device);
const deviceInfo = yield lockdownClient.getValue(null, null);
deviceName = deviceInfo['DeviceName'];
event.sender.send('device-name', deviceName);
});
meaco(function* doAfcExample() {
const lockdownClient = yield libijs.lockdownd.getClient(device, "libijs", false);
const deviceInfo = yield lockdownClient.getValue(null, null);
return deviceInfo;
}).done(deviceInfo => {
event.sender.send('device-name', { success: true, name: deviceInfo['DeviceName'] });
}).error((e) => {
console.error('Error:', e);
}).catch((e) => {
console.log(e);
event.sender.send('device-name', { success: false, message: 'No device found. Please attach device.' });
});
}

ipcMain.handle('fetch-devices', async (event) => {
// If it's not ready, then enqueue for after
if (!isDeviceManagerReady) {
onDeviceManagerReady = () => {
sendDevice(event)
};
return;
} else {
sendDevice(event);
}
});

ipcMain.on('find-in-page', (e, text, options) => {
Expand Down
39 changes: 31 additions & 8 deletions js/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ function cfiToSortableValue(cfi) {
// Should make this use await/async pattern, but meaco makes this annoying, so
// I haven't done it yet.
ipcRenderer.on('plist-data', async function (_, info) {
// If the data is null, then we successfully read, but had no data
if (info.data == null) {
populate();
return;
}

if (info.file == 'books') {
let parsed = plist.parse(info.data)['Books'];
Expand Down Expand Up @@ -86,6 +91,12 @@ async function populate() {
let booksList = $('.books');
let annotationsList = $('.annotations');

if (Object.keys(listOfBooks).length == 0) {
document.getElementById('no-results').classList.remove('hidden');
} else {
document.getElementById('no-results').classList.add('hidden');
}

Object.keys(listOfBooks).sort((a, b) => listOfBooks[b]['annotations'].length - listOfBooks[a]['annotations'].length).forEach(bookHash => {
let bookElement = $(`
<div class="book" data-hash="${bookHash}" data-offset="0">
Expand Down Expand Up @@ -153,21 +164,31 @@ async function populate() {
});
}

ipcRenderer.on('device-name', function (_, name) {
ipcRenderer.on('error', function (_, error) {
$('.devices span')[0].innerHTML = error;
});

ipcRenderer.on('device-name', function (_, info) {
document.getElementById('refresh').disabled = false;

$('#devices button.device').remove();
$('#devices .device').remove();

if (name === null) {
$('#devices span')[0].innerHTML = 'No device found. Please attach device.';
if (!info.success) {
$('.devices span')[0].innerHTML = info.message;
} else {
$('#devices span')[0].innerHTML = 'Select device.';
$('.devices span')[0].innerHTML = '';
const button = $(`
<button class="device">
${name}
<i class="fas fa-mobile-screen"></i>${info.name}
</button>
`);
button.on('click', async () => {
$('.devices span')[0].innerHTML = '';
// Reset the local list of books
listOfBooks = {};
$('.book').remove();
$('.annotation').remove();
// Try and start fetching
await ipcRenderer.invoke('read-plist', '/Books/Purchases/Purchases.plist', 'books');
});
$('#devices').append(button);
Expand All @@ -176,7 +197,7 @@ ipcRenderer.on('device-name', function (_, name) {

async function doStuff() {
document.getElementById('refresh').disabled = true;
await ipcRenderer.invoke('get-device-name');
await ipcRenderer.invoke('fetch-devices');
}

ipcRenderer.on('found-in-page', (_, result) => {
Expand All @@ -197,7 +218,9 @@ $(document).ready(async () => {
}
// Hit enter anywhere to index through (or shift+enter to go back)
} else if (e.keyCode == 13) {
ipcRenderer.sendSync('find-in-page', currentSearch, { forward: !e.shiftKey, findNext: false, matchCase: false });
if (currentSearch !== '') {
ipcRenderer.sendSync('find-in-page', currentSearch, { forward: !e.shiftKey, findNext: false, matchCase: false });
}
// Escape to exit the selection
} else if (e.code == "Escape") {
searching = false;
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
},
"dependencies": {
"@electron/remote": "^2.1.2",
"@fortawesome/fontawesome-free": "^6.5.2",
"@lwahonen/ref-napi": "^4.0.8",
"jarvis-emitter": "^2.1.4",
"meaco": "^1.0.3",
Expand Down

0 comments on commit 29580d2

Please sign in to comment.