Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • dfn2/pling-store-development
  • azubieta/pling-store-development
  • skye111/pling-store-development
  • fischy0487/pling-store-development
  • mussah/pling-store-development
  • visdom/pling-store-development
  • violethaze74/pling-store-development
  • wh0eta/pling-store-development
  • walmar163/pling-store-development
  • eefaerber/pling-store-development
  • mutazawad/pling-store-development
  • petrovgeorgi/pling-store-development
  • alleykatt/pling-store-development
  • 1147008/pling-store-development
  • jc01-onwork/pling-store-development
  • arystan/pling-store-development
  • hasithalakshan596/pling-store-development
  • motrmtl/pling-store-development
  • zakirhossain7745/pling-store-development
  • marcuseier/pling-store-development
  • rakansherif23/pling-store-development
  • badr2872/pling-store-development
  • dado105/pling-store-development
  • foolish13/pling-store-development
  • alex0115201/pling-store-development
  • kungfu8edora/pling-store-development
  • cxslucyfer/pling-store-development
  • khmisa4500/pling-store-development
  • androny22-77/pling-store-development
  • asus-bd24/pling-store-development
30 results
Show changes
Commits on Source (100)
Showing
with 216 additions and 401 deletions
build_*/
node_modules/
dist/
ocs-manager
......@@ -8,5 +8,5 @@ appimage:
- ./scripts/package appimage
artifacts:
paths:
- build_*/pling-store*.AppImage
- build_*/pling-store*.AppImage*
expire_in: 2 days
react: npm start
electron: node src/electron-wait-react
\ No newline at end of file
# pling-store
# Pling-Store
Pling store electron
\ No newline at end of file
Pling-Store is a Content Management App for OCS-compatible websites like opendesktop.org, gnome-look.org, etc.
It allows to download and install applications, desktop themes, icon themes, wallpapers, or mouse cursors
under various desktop environments using the "Install"-button.
Currently supported are these desktop environments:
KDE Plasma, Gnome, XFCE, Mate, Cinnamon, Budgie, LXQt, Elementary and Enlightenment.
## Usage
Using the Appimage package format, it should work on any distro like Ubuntu, Debian, Arch, Suse, Redhat and many more.
### Best with AppImageLauncher
If you never used an Appimage before, we recommend this tool to make AppImages run, install/uninstall and update on your Linux OS:
https://www.pling.com/p/1228228/
*Please see if AppImageLauncher offers native packages for your distro, if not, you may request it in the issue section.*
After installing AppImageLauncher, you can simply Double-Click on the Pling-Store Appimage to run or install it.
### Manual Run
To try the Pling-Store without installing, you can simply [make it executable](https://youtu.be/nzZ6Ikc7juw?t=78) and (double-)click on it.
## Development
The Pling-Store is a regular electron app plus the [ocs-manager](https://git.opendesktop.org/akiraohgaki/ocs-manager/). The first acts as a presentation
layer and the second is the one who handles the intallation of the different products.
### Project Setup
```
npm install
curl -fsSL -o node_modules/.bin/ocs-manager https://git.opendesktop.org/akiraohgaki/ocs-manager/uploads/d3dc42436b82d11360ebc96b38d4aaf4/ocs-manager-0.8.1-1-x86_64.AppImage
chmod +x node_modules/.bin/ocs-manager
```
### AppImage Generation
`./scripts/package appimage`
.icon-pling-store {
.icon-ocs-store {
background-image: url(app-icons/pling-store.svg);
}
......@@ -18,8 +18,8 @@
</head>
<body>
<app-root></app-root>
<script>
require = require('esm')(module);
module.exports = require('./scripts/renderers/browser-window.js');
......
const fs = require('fs');
const {spawn} = require('child_process');
const {app, BrowserWindow, BrowserView, ipcMain} = require('electron');
const {app, BrowserWindow, ipcMain} = require('electron');
const ElectronStore = require('electron-store');
const request = require('request');
// Set configs dir
app.setPath("userData", app.getPath("appData") + "/OCS-Store")
const appPackage = require('../package.json');
const appConfig = require('./configs/application.json');
const ocsManagerConfig = require('./configs/ocs-manager.json');
const isDebugMode = process.argv.includes('--debug');
const previewpicDirectory = `${app.getPath('userData')}/previewpic`;
const windowIcon = `${__dirname}/images/app-icons/ocs-store.png`;
const windowIndexFileUrl = `file://${__dirname}/index.html`;
const viewSessionPartition = 'persist:opendesktop';
const viewPreloadScript = `${__dirname}/scripts/renderers/browser-view.js`;
const windowIcon = `${__dirname}/images/app-icons/pling-store.png`;
const indexFileUrl = `file://${__dirname}/index.html`;
const appConfigStoreStorage = 'application';
let mainWindow = null;
let mainView = null;
let ocsManager = null;
let ocsManagerUrl = '';
......@@ -32,7 +32,8 @@ async function startOcsManager() {
}
};
ocsManager = spawn(ocsManagerConfig.bin, ['-p', ocsManagerConfig.port]);
ocsManager = spawn(ocsManagerConfig.bin, ['-p', ocsManagerConfig.port, '--appFile', process.env.APPIMAGE]);
ocsManager.stdout.on('data', (data) => {
console.log(`[${ocsManagerConfig.bin}] ${data}`);
......@@ -62,7 +63,6 @@ async function startOcsManager() {
function stopOcsManager() {
if (ocsManager) {
ocsManager.kill();
ocsManager = null;
ocsManagerUrl = '';
}
}
......@@ -87,6 +87,13 @@ function createWindow() {
}
});
if (!isDebugMode) {
mainWindow.setMenu(null);
}
mainWindow.loadURL(indexFileUrl);
mainWindow.maximize();
mainWindow.on('close', () => {
const appConfigStore = new ElectronStore({name: appConfigStoreStorage});
appConfigStore.set('windowBounds', mainWindow.getBounds());
......@@ -94,151 +101,18 @@ function createWindow() {
mainWindow.on('closed', () => {
mainWindow = null;
if (mainView) {
mainView.destroy();
mainView = null;
}
});
if (isDebugMode) {
mainWindow.webContents.openDevTools({mode: 'detach'});
}
else {
mainWindow.setMenu(null);
mainWindow.webContents.openDevTools();
}
mainWindow.loadURL(windowIndexFileUrl);
createView();
}
function createView() {
const detectOcsApiInfo = (url) => {
// Detect provider key and content id from page url
// https://www.opendesktop.org/s/Gnome/p/123456789/?key=val#hash
//
// providerKey = https://www.opendesktop.org/ocs/v1/
// contentId = 123456789
const info = {
providerKey: '',
contentId: ''
};
const matches = url.match(/(https?:\/\/[^/]+).*\/p\/([^/?#]+)/);
if (matches) {
info.providerKey = `${matches[1]}/ocs/v1/`;
info.contentId = matches[2];
}
return info;
};
mainView = new BrowserView({
webPreferences: {
nodeIntegration: false,
partition: viewSessionPartition,
preload: viewPreloadScript
}
});
mainWindow.setBrowserView(mainView);
const windowBounds = mainWindow.getBounds();
mainView.setBounds({
x: 0,
y: 0,
width: windowBounds.width,
height: windowBounds.height
});
mainView.setAutoResize({
width: true,
height: true
});
mainView.webContents.on('did-start-loading', () => {
mainWindow.webContents.send('browserView_loading', {isLoading: true});
});
mainView.webContents.on('did-stop-loading', () => {
mainWindow.webContents.send('browserView_loading', {isLoading: false});
});
mainView.webContents.on('dom-ready', () => {
mainWindow.webContents.send('browserView_page', {
url: mainView.webContents.getURL(),
title: mainView.webContents.getTitle(),
canGoBack: mainView.webContents.canGoBack(),
canGoForward: mainView.webContents.canGoForward()
});
if (isDebugMode) {
mainView.webContents.openDevTools({mode: 'detach'});
}
mainView.webContents.send('ipcMessage');
});
mainView.webContents.on('new-window', (event, url) => {
if (url.startsWith('http://') || url.startsWith('https://')) {
event.preventDefault();
mainWindow.webContents.send('ocsManager_openUrl', {url: url});
}
});
mainView.webContents.on('will-navigate', (event, url) => {
if (url.startsWith('ocs://') || url.startsWith('ocss://')) {
event.preventDefault();
const info = detectOcsApiInfo(mainView.webContents.getURL());
mainWindow.webContents.send('ocsManager_getItemByOcsUrl', {url: url, ...info});
}
});
ipcMain.on('browserView_loadUrl', (event, url) => {
mainView.webContents.loadURL(url);
event.returnValue = undefined;
});
ipcMain.on('browserView_getUrl', (event) => {
event.returnValue = mainView.webContents.getURL();
});
ipcMain.on('browserView_getTitle', (event) => {
event.returnValue = mainView.webContents.getTitle();
});
ipcMain.on('browserView_goBack', (event) => {
mainView.webContents.goBack();
event.returnValue = undefined;
});
ipcMain.on('browserView_goForward', (event) => {
mainView.webContents.goForward();
event.returnValue = undefined;
});
ipcMain.on('browserView_reload', (event) => {
mainView.webContents.reload();
event.returnValue = undefined;
});
ipcMain.on('browserView_stop', (event) => {
mainView.webContents.stop();
event.returnValue = undefined;
});
//ipcMain.on('ipcMessage', (event) => {});
const appConfigStore = new ElectronStore({name: appConfigStoreStorage});
const startPage = appConfigStore.get('startPage');
mainView.webContents.loadURL(startPage);
}
function isFile(path) {
try {
const stats = fs.statSync(path);
return stats.isFile();
}
catch (error) {
} catch (error) {
console.error(error);
return false;
}
......@@ -248,8 +122,7 @@ function isDirectory(path) {
try {
const stats = fs.statSync(path);
return stats.isDirectory();
}
catch (error) {
} catch (error) {
console.error(error);
return false;
}
......@@ -269,24 +142,14 @@ function previewpicFilename(itemKey) {
return btoa(itemKey).slice(-255);
}
function downloadPreviewpic(itemKey) {
const selector = 'meta[property="og:image"]';
mainView.webContents.executeJavaScript(
`document.querySelector('${selector}').content`,
false,
(result) => {
const previewpicUrl = result || '';
if (previewpicUrl) {
if (!isDirectory(previewpicDirectory)) {
fs.mkdirSync(previewpicDirectory);
}
const path = `${previewpicDirectory}/${previewpicFilename(itemKey)}`;
request.get(previewpicUrl).on('error', (error) => {
console.error(error);
}).pipe(fs.createWriteStream(path));
}
}
);
function downloadPreviewpic(itemKey, url) {
if (!isDirectory(previewpicDirectory)) {
fs.mkdirSync(previewpicDirectory);
}
const path = `${previewpicDirectory}/${previewpicFilename(itemKey)}`;
request.get(url).on('error', (error) => {
console.error(error);
}).pipe(fs.createWriteStream(path));
}
function removePreviewpic(itemKey) {
......@@ -299,8 +162,7 @@ function removePreviewpic(itemKey) {
app.on('ready', async () => {
if (await startOcsManager()) {
createWindow();
}
else {
} else {
app.quit();
}
});
......@@ -321,7 +183,7 @@ app.on('activate', () => {
}
});
/*app.on('web-contents-created', (event, webContents) => {
app.on('web-contents-created', (event, webContents) => {
if (webContents.getType() === 'webview') {
webContents.on('will-navigate', (event, url) => {
if (url.startsWith('ocs://') || url.startsWith('ocss://')) {
......@@ -330,7 +192,7 @@ app.on('activate', () => {
}
});
}
});*/
});
ipcMain.on('app', (event, key) => {
const data = {
......@@ -357,22 +219,24 @@ ipcMain.on('store', (event, key, value) => {
event.returnValue = key ? appConfigStore.get(key) : appConfigStore.store;
});
ipcMain.on('checkForUpdates', () => {
// TODO -> add check for updates method?
ocsManager = spawn(ocsManagerConfig.bin, ['-p', ocsManagerConfig.port, '--appFile', process.env.APPIMAGE]);
console.log(ocsManager);
});
ipcMain.on('previewpic', (event, kind, itemKey, url) => {
if (kind === 'directory') {
event.returnValue = previewpicDirectory;
}
else if (kind === 'path' && itemKey) {
} else if (kind === 'path' && itemKey) {
event.returnValue = `${previewpicDirectory}/${previewpicFilename(itemKey)}`;
}
else if (kind === 'download' && itemKey && url) {
} else if (kind === 'download' && itemKey && url) {
downloadPreviewpic(itemKey, url);
event.returnValue = undefined;
}
else if (kind === 'remove' && itemKey) {
} else if (kind === 'remove' && itemKey) {
removePreviewpic(itemKey);
event.returnValue = undefined;
}
else {
} else {
event.returnValue = false;
}
});
......@@ -41,7 +41,7 @@ export default class AboutdialogComponent extends BaseComponent {
padding: 1em;
text-align: center;
}
div[slot="content"] figure.icon-pling-store {
div[slot="content"] figure.icon-ocs-store {
display: inline-block;
width: 128px;
height: 128px;
......@@ -58,7 +58,7 @@ export default class AboutdialogComponent extends BaseComponent {
<app-dialog data-width="500px" data-footer-state="inactive">
<h3 slot="header">About This App</h3>
<div slot="content">
<figure class="icon-pling-store"></figure>
<figure class="icon-ocs-store"></figure>
<h4>${this.state.productName}</h4>
<p>Version ${this.state.version}</p>
<p>${this.state.description}</p>
......@@ -87,7 +87,7 @@ export default class AboutdialogComponent extends BaseComponent {
_handleClick(event) {
if (event.target.closest('a')) {
event.preventDefault();
this.dispatch('browserView_loadUrl', {url: event.target.closest('a').href});
this.dispatch('webview_loadUrl', {url: event.target.closest('a').href});
this.close();
}
}
......
......@@ -15,24 +15,24 @@ export default class OmniboxComponent extends BaseComponent {
this.contentRoot.addEventListener('click', this._handleClick.bind(this));
this._viewHandler_browserView_loading = this._viewHandler_browserView_loading.bind(this);
this._viewHandler_browserView_page = this._viewHandler_browserView_page.bind(this);
this._viewHandler_webview_loading = this._viewHandler_webview_loading.bind(this);
this._viewHandler_webview_page = this._viewHandler_webview_page.bind(this);
this._viewHandler_ocsManager_updateAvailableItems = this._viewHandler_ocsManager_updateAvailableItems.bind(this);
this._viewHandler_ocsManager_metadataSet = this._viewHandler_ocsManager_metadataSet.bind(this);
}
componentConnectedCallback() {
this.getStateManager().viewHandler
.add('browserView_loading', this._viewHandler_browserView_loading)
.add('browserView_page', this._viewHandler_browserView_page)
.add('webview_loading', this._viewHandler_webview_loading)
.add('webview_page', this._viewHandler_webview_page)
.add('ocsManager_updateAvailableItems', this._viewHandler_ocsManager_updateAvailableItems)
.add('ocsManager_metadataSet', this._viewHandler_ocsManager_metadataSet);
}
componentDisconnectedCallback() {
this.getStateManager().viewHandler
.remove('browserView_loading', this._viewHandler_browserView_loading)
.remove('browserView_page', this._viewHandler_browserView_page)
.remove('webview_loading', this._viewHandler_webview_loading)
.remove('webview_page', this._viewHandler_webview_page)
.remove('ocsManager_updateAvailableItems', this._viewHandler_ocsManager_updateAvailableItems)
.remove('ocsManager_metadataSet', this._viewHandler_ocsManager_metadataSet);
}
......@@ -231,12 +231,14 @@ export default class OmniboxComponent extends BaseComponent {
<h4><i class="material-icons md-small">home</i> Choose Startpage</h4>
<nav>
<ul>
<li><app-button data-action="browserView_startPage" data-url="https://www.opendesktop.org/">pling.com</app-button></li>
<li><app-button data-action="browserView_startPage" data-url="https://www.opendesktop.org/s/Gnome">gnome-look.org</app-button></li>
<li><app-button data-action="browserView_startPage" data-url="https://store.kde.org/">store.kde.org</app-button></li>
<li><app-button data-action="browserView_startPage" data-url="https://www.opendesktop.org/s/XFCE">xfce-look.org</app-button></li>
<li><app-button data-action="browserView_startPage" data-url="https://www.opendesktop.org/s/Window-Managers">box-look.org</app-button></li>
<li><app-button data-action="browserView_startPage" data-url="https://www.opendesktop.org/s/Enlightenment">enlightenment-themes.org</app-button></li>
<li><app-button data-action="webview_startPage" data-url="https://www.pling.com/">pling.com</app-button></li>
<li><app-button data-action="webview_startPage" data-url="https://www.appimagehub.com/">Appimagehub.com</app-button></li>
<li><app-button data-action="webview_startPage" data-url="https://store.kde.org/">KDE</app-button></li>
<li><app-button data-action="webview_startPage" data-url="https://www.pling.com/s/Artwork">Artwork</app-button></li>
<li><app-button data-action="webview_startPage" data-url="https://www.pling.com/s/Gnome">Gnome</app-button></li>
<li><app-button data-action="webview_startPage" data-url="https://www.pling.com/s/Comics">Comics</app-button></li>
<li><app-button data-action="webview_startPage" data-url="https://www.pling.com/s/XFCE">XFCE</app-button></li>
<li><app-button data-action="webview_startPage" data-url="https://www.pling.com/s/Videos">Videos</app-button></li>
</ul>
</nav>
</div>
......@@ -247,12 +249,12 @@ export default class OmniboxComponent extends BaseComponent {
}
componentUpdatedCallback() {
if (this.contentRoot.querySelector('app-button[data-action="browserView_startPage"][data-checked]')) {
this.contentRoot.querySelector('app-button[data-action="browserView_startPage"][data-checked]').removeAttribute('data-checked');
if (this.contentRoot.querySelector('app-button[data-action="webview_startPage"][data-checked]')) {
this.contentRoot.querySelector('app-button[data-action="webview_startPage"][data-checked]').removeAttribute('data-checked');
}
if (this.contentRoot.querySelector(`app-button[data-action="browserView_startPage"][data-url="${this.state.startPage}"]`)) {
this.contentRoot.querySelector(`app-button[data-action="browserView_startPage"][data-url="${this.state.startPage}"]`).setAttribute('data-checked', 'data-checked');
if (this.contentRoot.querySelector(`app-button[data-action="webview_startPage"][data-url="${this.state.startPage}"]`)) {
this.contentRoot.querySelector(`app-button[data-action="webview_startPage"][data-url="${this.state.startPage}"]`).setAttribute('data-checked', 'data-checked');
}
}
......@@ -300,8 +302,8 @@ export default class OmniboxComponent extends BaseComponent {
this.dispatch('ocsManager_openUrl', {url: target.getAttribute('data-url')});
break;
}
case 'browserView_startPage': {
this.dispatch('browserView_startPage', {url: target.getAttribute('data-url')});
case 'webview_startPage': {
this.dispatch('webview_startPage', {url: target.getAttribute('data-url')});
this.close();
break;
}
......@@ -313,12 +315,12 @@ export default class OmniboxComponent extends BaseComponent {
}
}
_viewHandler_browserView_loading(state) {
_viewHandler_webview_loading(state) {
const indicator = this.contentRoot.querySelector('div[data-omnibox] app-indicator');
state.isLoading ? indicator.start() : indicator.stop();
}
_viewHandler_browserView_page(state) {
_viewHandler_webview_page(state) {
this.update({...this.state, ...state});
}
......
......@@ -5,8 +5,7 @@ import Chirit from '../../libs/chirit/Chirit.js';
import OcsManagerApi from '../api/OcsManagerApi.js';
import GeneralHandler from '../handlers/GeneralHandler.js';
//import WebviewHandler from '../handlers/WebviewHandler.js';
import BrowserViewHandler from '../handlers/BrowserViewHandler.js';
import WebviewHandler from '../handlers/WebviewHandler.js';
import OcsManagerHandler from '../handlers/OcsManagerHandler.js';
import BaseComponent from './common/BaseComponent.js';
......@@ -21,8 +20,7 @@ export default class RootComponent extends BaseComponent {
const ocsManagerApi = new OcsManagerApi(ipcRenderer.sendSync('ocs-manager', 'url'));
new GeneralHandler(this._stateManager, ipcRenderer);
//new WebviewHandler(this._stateManager, ipcRenderer);
new BrowserViewHandler(this._stateManager, ipcRenderer);
new WebviewHandler(this._stateManager, ipcRenderer);
new OcsManagerHandler(this._stateManager, ipcRenderer, ocsManagerApi);
}
......@@ -41,7 +39,7 @@ export default class RootComponent extends BaseComponent {
<app-page id="browser">
<app-toolbar slot="header"></app-toolbar>
<!--<app-webview slot="content"></app-webview>-->
<app-webview slot="content"></app-webview>
</app-page>
<app-collectiondialog></app-collectiondialog>
......
......@@ -3,17 +3,17 @@ import BaseComponent from './common/BaseComponent.js';
export default class SplashscreenComponent extends BaseComponent {
init() {
this._viewHandler_browserView_loading = this._viewHandler_browserView_loading.bind(this);
this._viewHandler_webview_loading = this._viewHandler_webview_loading.bind(this);
}
componentConnectedCallback() {
this.getStateManager().viewHandler
.add('browserView_loading', this._viewHandler_browserView_loading);
.add('webview_loading', this._viewHandler_webview_loading);
}
componentDisconnectedCallback() {
this.getStateManager().viewHandler
.remove('browserView_loading', this._viewHandler_browserView_loading);
.remove('webview_loading', this._viewHandler_webview_loading);
}
render() {
......@@ -31,7 +31,7 @@ export default class SplashscreenComponent extends BaseComponent {
align-items: center;
justify-content: center;
}
div[slot="content"] figure.icon-pling-store {
div[slot="content"] figure.icon-ocs-store {
display: inline-block;
width: 128px;
height: 128px;
......@@ -47,7 +47,7 @@ export default class SplashscreenComponent extends BaseComponent {
<app-dialog data-width="400px" data-height="300px"
data-state="active" data-header-state="inactive" data-footer-state="inactive" data-auto-close-state="inactive">
<div slot="content">
<figure class="icon-pling-store"></figure>
<figure class="icon-ocs-store"></figure>
<h3>Welcome to ${document.title}</h3>
<p>Loading...</p>
</div>
......@@ -55,7 +55,7 @@ export default class SplashscreenComponent extends BaseComponent {
`;
}
_viewHandler_browserView_loading(state) {
_viewHandler_webview_loading(state) {
if (!state.isLoading) {
this.contentRoot.querySelector('app-dialog').close();
// Splash screen only shows when app launch, so remove it
......
import BaseComponent from './common/BaseComponent.js';
const {ipcRenderer} = require('electron');
export default class ToolbarComponent extends BaseComponent {
init() {
this.contentRoot.addEventListener('click', this._handleClick.bind(this));
this._viewHandler_browserView_loading = this._viewHandler_browserView_loading.bind(this);
this._viewHandler_browserView_page = this._viewHandler_browserView_page.bind(this);
this._ipcRenderer = ipcRenderer;
this._viewHandler_webview_loading = this._viewHandler_webview_loading.bind(this);
this._viewHandler_webview_page = this._viewHandler_webview_page.bind(this);
this._viewHandler_ocsManager_updateAvailableItems = this._viewHandler_ocsManager_updateAvailableItems.bind(this);
this._viewHandler_ocsManager_metadataSet = this._viewHandler_ocsManager_metadataSet.bind(this);
}
componentConnectedCallback() {
this.getStateManager().viewHandler
.add('browserView_loading', this._viewHandler_browserView_loading)
.add('browserView_page', this._viewHandler_browserView_page)
.add('webview_loading', this._viewHandler_webview_loading)
.add('webview_page', this._viewHandler_webview_page)
.add('ocsManager_updateAvailableItems', this._viewHandler_ocsManager_updateAvailableItems)
.add('ocsManager_metadataSet', this._viewHandler_ocsManager_metadataSet);
}
componentDisconnectedCallback() {
this.getStateManager().viewHandler
.remove('browserView_loading', this._viewHandler_browserView_loading)
.remove('browserView_page', this._viewHandler_browserView_page)
.remove('webview_loading', this._viewHandler_webview_loading)
.remove('webview_page', this._viewHandler_webview_page)
.remove('ocsManager_updateAvailableItems', this._viewHandler_ocsManager_updateAvailableItems)
.remove('ocsManager_metadataSet', this._viewHandler_ocsManager_metadataSet);
}
......@@ -67,10 +68,10 @@ export default class ToolbarComponent extends BaseComponent {
}
}
app-iconbutton[data-action="browserView_reload"][data-state="inactive"] {
app-iconbutton[data-action="webview_reload"][data-state="inactive"] {
display: none;
}
app-iconbutton[data-action="browserView_stop"][data-state="inactive"] {
app-iconbutton[data-action="webview_stop"][data-state="inactive"] {
display: none;
}
......@@ -99,21 +100,21 @@ export default class ToolbarComponent extends BaseComponent {
<nav data-toolbar>
<ul>
<li>
<app-iconbutton data-action="browserView_goBack"
<app-iconbutton data-action="webview_goBack"
data-title="Back" data-icon="arrow_back" data-state="inactive"></app-iconbutton>
</li>
<li>
<app-iconbutton data-action="browserView_goForward"
<app-iconbutton data-action="webview_goForward"
data-title="Forward" data-icon="arrow_forward" data-state="inactive"></app-iconbutton>
</li>
<li>
<app-iconbutton data-action="browserView_reload"
<app-iconbutton data-action="webview_reload"
data-title="Reload" data-icon="refresh" data-state="active"></app-iconbutton>
<app-iconbutton data-action="browserView_stop"
<app-iconbutton data-action="webview_stop"
data-title="Stop" data-icon="close" data-state="inactive"></app-iconbutton>
</li>
<li>
<app-iconbutton data-action="browserView_startPage"
<app-iconbutton data-action="webview_startPage"
data-title="Startpage" data-icon="home"></app-iconbutton>
</li>
<li>
......@@ -121,16 +122,20 @@ export default class ToolbarComponent extends BaseComponent {
data-title="My Collection" data-icon="folder"></app-iconbutton><br>
<app-badge data-count="0" data-emphasis="high"></app-badge>
<app-badge data-count="0" data-emphasis="medium"></app-badge>
</li>
</li>
<li data-omnibox><app-omnibox></app-omnibox></li>
<li>
<app-iconbutton data-action="menu_open"
data-title="Other Operations..." data-icon="more_vert"></app-iconbutton><br>
<app-menu data-width="250px" data-offset-x="-220px">
<a slot="menuitem" href="#" data-action="browserView_appBugsPage">Report a Bug</a>
<a slot="menuitem" href="#" data-action="webview_appBugsPage">Report a Bug</a>
<a slot="menuitem" href="#" data-action="check_for_updates">Check for Updates</a>
<a slot="menuitem" href="#" data-action="general_about">About This App</a>
</app-menu>
</li>
<li>
<app-iconbutton data-action="login" data-title="Login" data-icon="account_circle" data-state="active"></app-iconbutton>
</li>
</ul>
</nav>
`;
......@@ -150,24 +155,24 @@ export default class ToolbarComponent extends BaseComponent {
}
switch (target.getAttribute('data-action')) {
case 'browserView_goBack': {
this.dispatch('browserView_goBack', {});
case 'webview_goBack': {
this.dispatch('webview_goBack', {});
break;
}
case 'browserView_goForward': {
this.dispatch('browserView_goForward', {});
case 'webview_goForward': {
this.dispatch('webview_goForward', {});
break;
}
case 'browserView_reload': {
this.dispatch('browserView_reload', {});
case 'webview_reload': {
this.dispatch('webview_reload', {});
break;
}
case 'browserView_stop': {
this.dispatch('browserView_stop', {});
case 'webview_stop': {
this.dispatch('webview_stop', {});
break;
}
case 'browserView_startPage': {
this.dispatch('browserView_startPage', {});
case 'webview_startPage': {
this.dispatch('webview_startPage', {});
break;
}
case 'ocsManager_collection': {
......@@ -178,8 +183,14 @@ export default class ToolbarComponent extends BaseComponent {
this.contentRoot.querySelector('app-menu').open();
break;
}
case 'browserView_appBugsPage': {
this.dispatch('browserView_appBugsPage', {});
case 'webview_appBugsPage': {
this.dispatch('webview_appBugsPage', {});
this.contentRoot.querySelector('app-menu').close();
break;
}
case 'check_for_updates':{
//this._ipcRenderer.send('checkForUpdates');
this.dispatch('ocsManager_checkForUpdates', {});
this.contentRoot.querySelector('app-menu').close();
break;
}
......@@ -188,20 +199,24 @@ export default class ToolbarComponent extends BaseComponent {
this.contentRoot.querySelector('app-menu').close();
break;
}
case 'login':{
this.dispatch('webview_loginPage', {});
break;
}
}
}
_viewHandler_browserView_loading(state) {
this.contentRoot.querySelector('app-iconbutton[data-action="browserView_reload"]')
_viewHandler_webview_loading(state) {
this.contentRoot.querySelector('app-iconbutton[data-action="webview_reload"]')
.setAttribute('data-state', state.isLoading ? 'inactive' : 'active');
this.contentRoot.querySelector('app-iconbutton[data-action="browserView_stop"]')
this.contentRoot.querySelector('app-iconbutton[data-action="webview_stop"]')
.setAttribute('data-state', state.isLoading ? 'active' : 'inactive');
}
_viewHandler_browserView_page(state) {
this.contentRoot.querySelector('app-iconbutton[data-action="browserView_goBack"]')
_viewHandler_webview_page(state) {
this.contentRoot.querySelector('app-iconbutton[data-action="webview_goBack"]')
.setAttribute('data-state', state.canGoBack ? 'active' : 'inactive');
this.contentRoot.querySelector('app-iconbutton[data-action="browserView_goForward"]')
this.contentRoot.querySelector('app-iconbutton[data-action="webview_goForward"]')
.setAttribute('data-state', state.canGoForward ? 'active' : 'inactive');
}
......
......@@ -102,6 +102,11 @@ export default class WebviewComponent extends BaseComponent {
this._webview.addEventListener('did-stop-loading', () => {
this.dispatch('webview_loading', {isLoading: false});
// workaround for Input cursor invisible after navigation in webview
// details at https://github.com/electron/electron/issues/14474
this._webview.blur();
this._webview.focus();
});
this._webview.addEventListener('dom-ready', () => {
......
......@@ -126,4 +126,4 @@ export default class MenuComponent extends BaseComponent {
}
}
}
}
\ No newline at end of file
......@@ -31,8 +31,8 @@ ToolbarComponent.define('app-toolbar');
import OmniboxComponent from './OmniboxComponent.js';
OmniboxComponent.define('app-omnibox');
//import WebviewComponent from './WebviewComponent.js';
//WebviewComponent.define('app-webview');
import WebviewComponent from './WebviewComponent.js';
WebviewComponent.define('app-webview');
import CollectiondialogComponent from './CollectiondialogComponent.js';
CollectiondialogComponent.define('app-collectiondialog');
......
export default class BrowserViewHandler {
constructor(stateManager, ipcRenderer) {
this._stateManager = stateManager;
this._ipcRenderer = ipcRenderer;
this._appPackage = this._ipcRenderer.sendSync('app', 'package');
this._startPage = this._ipcRenderer.sendSync('store', 'startPage');
this._subscribe();
}
_subscribe() {
this._ipcRenderer.on('browserView_loading', (event, data) => {
this._stateManager.dispatch('browserView_loading', data);
});
this._ipcRenderer.on('browserView_page', (event, data) => {
this._stateManager.dispatch('browserView_page', data);
});
this._stateManager.actionHandler
.add('browserView_loading', (data) => {
return {isLoading: data.isLoading};
})
.add('browserView_page', (data) => {
return {
startPage: this._startPage,
url: data.url,
title: data.title,
canGoBack: data.canGoBack,
canGoForward: data.canGoForward
};
})
.add('browserView_startPage', (data) => {
if (data.url) {
this._startPage = data.url;
this._ipcRenderer.sendSync('store', 'startPage', this._startPage);
}
this._ipcRenderer.sendSync('browserView_loadUrl', this._startPage);
return false;
})
.add('browserView_loadUrl', (data) => {
this._ipcRenderer.sendSync('browserView_loadUrl', data.url);
return false;
})
.add('browserView_goBack', () => {
this._ipcRenderer.sendSync('browserView_goBack');
return false;
})
.add('browserView_goForward', () => {
this._ipcRenderer.sendSync('browserView_goForward');
return false;
})
.add('browserView_reload', () => {
this._ipcRenderer.sendSync('browserView_reload');
return false;
})
.add('browserView_stop', () => {
this._ipcRenderer.sendSync('browserView_stop');
return false;
})
.add('browserView_appBugsPage', () => {
this._ipcRenderer.sendSync('browserView_loadUrl', this._appPackage.bugs);
return false;
});
}
}
......@@ -8,7 +8,7 @@ export default class OcsManagerHandler {
this._previewpicDirectory = this._ipcRenderer.sendSync('previewpic', 'directory');
this._installTypes = {};
//this._webviewComponent = null;
this._webviewComponent = null;
this._collectiondialogComponent = null;
this._subscribe();
......@@ -16,19 +16,11 @@ export default class OcsManagerHandler {
}
_subscribe() {
this._ipcRenderer.on('ocsManager_openUrl', (event, data) => {
this._stateManager.dispatch('ocsManager_openUrl', data);
});
this._ipcRenderer.on('ocsManager_getItemByOcsUrl', (event, data) => {
this._stateManager.dispatch('ocsManager_getItemByOcsUrl', data);
});
this._stateManager.actionHandler
/*.add('webview_activate', (data) => {
.add('webview_activate', (data) => {
this._webviewComponent = data.component;
return {isActivated: true};
})*/
})
.add('ocsManager_activate', (data) => {
this._collectiondialogComponent = data.component;
return {isActivated: true};
......@@ -152,6 +144,12 @@ export default class OcsManagerHandler {
return false;
})
.add('ocsManager_checkForUpdates', () => {
console.log('checkForUpdates');
this._ocsManagerApi.send('UpdateHandler::checkAppUpdate', []).then(function(res){
console.log(res)
});
})
.add('ocsManager_update', (data) => {
this._ocsManagerApi.send('UpdateHandler::update', [data.itemKey]);
return false;
......@@ -185,7 +183,29 @@ export default class OcsManagerHandler {
});
// Download preview picture
this._ipcRenderer.sendSync('previewpic', 'download', message.data[0].metadata.url);
const selector = 'meta[property="og:image"]';
this._webviewComponent.executeJavaScript(
`document.querySelector('${selector}').content`,
false,
(result) => {
let previewpicUrl = result || '';
// FIXME: previewpic API maybe deprecated
/*
if (!previewpicUrl
&& message.data[0].metadata.command === 'install'
&& message.data[0].metadata.provider
&& message.data[0].metadata.content_id
) {
previewpicUrl = `${message.data[0].metadata.provider}content/previewpic/${message.data[0].metadata.content_id}`;
}
*/
if (previewpicUrl) {
this._ipcRenderer.sendSync('previewpic', 'download', message.data[0].metadata.url, previewpicUrl);
}
}
);
})
.set('ItemHandler::downloadFinished', (message) => {
if (message.data[0].status !== 'success_download') {
......
......@@ -73,6 +73,10 @@ export default class WebviewHandler {
.add('webview_appBugsPage', () => {
this._webviewComponent.loadUrl(this._appPackage.bugs);
return false;
})
.add('webview_loginPage', () => {
this._webviewComponent.loadUrl('https://www.pling.com/login');
return false;
});
}
......
const {ipcRenderer} = require('electron');
function applySmoothScroll() {
let requestId = null;
let frame = 0;
const frameMax = 50;
let amount = 0;
const amountMax = 7;
let deltaX = 0;
let deltaY = 0;
let scrollLeft = 0;
let scrollTop = 0;
const easeOut = (p) => {
return p * (2 - p);
};
const scroll = () => {
frame++;
document.scrollingElement.scrollTo({
left: scrollLeft + (deltaX * easeOut(frame / frameMax)),
top: scrollTop + (deltaY * easeOut(frame / frameMax))
});
if (frame === frameMax) {
frame = 0;
amount = 0;
cancelAnimationFrame(requestId);
}
else {
requestId = requestAnimationFrame(scroll);
}
};
document.scrollingElement.addEventListener('wheel', (event) => {
event.preventDefault();
if (Math.sign(deltaX) !== Math.sign(event.deltaX)
|| Math.sign(deltaY) !== Math.sign(event.deltaY)
) {
amount = 0;
}
if (amount < amountMax) {
amount++;
}
deltaX = event.deltaX * amount;
deltaY = event.deltaY * amount;
scrollLeft = document.scrollingElement.scrollLeft;
scrollTop = document.scrollingElement.scrollTop;
if (frame) {
frame = 0;
cancelAnimationFrame(requestId);
}
scroll();
});
}
/*
function detectUserProfile() {
const profileMenu = document.querySelector('[rel="profile-menu"]');
if (profileMenu) {
const userName = profileMenu.querySelector('span').innerHTML;
const userImage = profileMenu.querySelector('img').src;
ipcRenderer.sendToHost('user-profile', userName, userImage);
}
}
*/
ipcRenderer.on('ipc-message', () => {
applySmoothScroll();
//detectUserProfile();
});