Add a badge to the dock for downloaded files

This commit is contained in:
6ea86b96 2017-06-24 15:57:37 +07:00
parent 56aa4d2255
commit 0214422e6b
8 changed files with 146 additions and 0 deletions

View file

@ -11,6 +11,10 @@ import { selectResolvingUris } from "selectors/content";
import { selectCostInfoForUri } from "selectors/cost_info"; import { selectCostInfoForUri } from "selectors/cost_info";
import { doOpenModal } from "actions/app"; import { doOpenModal } from "actions/app";
import { doClaimEligiblePurchaseRewards } from "actions/rewards"; import { doClaimEligiblePurchaseRewards } from "actions/rewards";
import { selectBadgeNumber } from "selectors/app";
import { selectTotalDownloadProgress } from "selectors/file_info";
import setBadge from "util/setBadge";
import setProgressBar from "util/setProgressBar";
import batchActions from "util/batchActions"; import batchActions from "util/batchActions";
export function doResolveUri(uri) { export function doResolveUri(uri) {
@ -121,6 +125,11 @@ export function doUpdateLoadStatus(uri, outpoint) {
fileInfo, fileInfo,
}, },
}); });
const badgeNumber = selectBadgeNumber(getState());
setBadge(badgeNumber === 0 ? "" : `${badgeNumber}`);
const totalProgress = selectTotalDownloadProgress(getState());
setProgressBar(totalProgress);
} else { } else {
// ready to play // ready to play
const { total_bytes, written_bytes } = fileInfo; const { total_bytes, written_bytes } = fileInfo;
@ -135,6 +144,10 @@ export function doUpdateLoadStatus(uri, outpoint) {
progress, progress,
}, },
}); });
const totalProgress = selectTotalDownloadProgress(getState());
setProgressBar(totalProgress);
setTimeout(() => { setTimeout(() => {
dispatch(doUpdateLoadStatus(uri, outpoint)); dispatch(doUpdateLoadStatus(uri, outpoint));
}, 250); }, 250);

View file

@ -4,6 +4,7 @@ export const CLOSE_MODAL = "CLOSE_MODAL";
export const HISTORY_BACK = "HISTORY_BACK"; export const HISTORY_BACK = "HISTORY_BACK";
export const SHOW_SNACKBAR = "SHOW_SNACKBAR"; export const SHOW_SNACKBAR = "SHOW_SNACKBAR";
export const REMOVE_SNACKBAR_SNACK = "REMOVE_SNACKBAR_SNACK"; export const REMOVE_SNACKBAR_SNACK = "REMOVE_SNACKBAR_SNACK";
export const WINDOW_FOCUSED = "WINDOW_FOCUSED";
export const DAEMON_READY = "DAEMON_READY"; export const DAEMON_READY = "DAEMON_READY";

View file

@ -9,6 +9,8 @@ import SplashScreen from "component/splash.js";
import AuthOverlay from "component/authOverlay"; import AuthOverlay from "component/authOverlay";
import { doChangePath, doNavigate, doDaemonReady } from "actions/app"; import { doChangePath, doNavigate, doDaemonReady } from "actions/app";
import { toQueryString } from "util/query_params"; import { toQueryString } from "util/query_params";
import { selectBadgeNumber } from "selectors/app";
import * as types from "constants/action_types";
const env = ENV; const env = ENV;
const { remote, ipcRenderer, shell } = require("electron"); const { remote, ipcRenderer, shell } = require("electron");
@ -71,6 +73,25 @@ document.addEventListener("click", event => {
} }
}); });
const application = remote.app;
const dock = application.dock;
const win = remote.BrowserWindow.getFocusedWindow();
// Clear the badge when the window is focused
win.on("focus", () => {
if (!dock) return;
app.store.dispatch({ type: types.WINDOW_FOCUSED });
dock.setBadge("");
});
const updateProgress = () => {
const state = app.store.getState();
const progress = selectTotalDownloadProgress(state);
win.setProgressBar(progress || -1);
};
const initialState = app.store.getState(); const initialState = app.store.getState();
// import whyDidYouUpdate from "why-did-you-update"; // import whyDidYouUpdate from "why-did-you-update";

View file

@ -7,6 +7,10 @@ const currentPath = () => {
else return "/discover"; else return "/discover";
}; };
const { remote } = require("electron");
const application = remote.app;
const win = remote.BrowserWindow.getFocusedWindow();
const reducers = {}; const reducers = {};
const defaultState = { const defaultState = {
isLoaded: false, isLoaded: false,
@ -16,6 +20,7 @@ const defaultState = {
daemonReady: false, daemonReady: false,
obscureNsfw: !lbry.getClientSetting("showNsfw"), obscureNsfw: !lbry.getClientSetting("showNsfw"),
hasSignature: false, hasSignature: false,
badgeNumber: 0,
}; };
reducers[types.DAEMON_READY] = function(state, action) { reducers[types.DAEMON_READY] = function(state, action) {
@ -120,6 +125,23 @@ reducers[types.REMOVE_SNACKBAR_SNACK] = function(state, action) {
}); });
}; };
reducers[types.DOWNLOADING_COMPLETED] = function(state, action) {
const badgeNumber = state.badgeNumber;
// Don't update the badge number if the window is focused
if (win.isFocused()) return Object.assign({}, state);
return Object.assign({}, state, {
badgeNumber: badgeNumber + 1,
});
};
reducers[types.WINDOW_FOCUSED] = function(state, action) {
return Object.assign({}, state, {
badgeNumber: 0,
});
};
export default function reducer(state = defaultState, action) { export default function reducer(state = defaultState, action) {
const handler = reducers[action.type]; const handler = reducers[action.type];
if (handler) return handler(state, action); if (handler) return handler(state, action);

View file

@ -190,3 +190,8 @@ export const selectSnackBarSnacks = createSelector(
selectSnackBar, selectSnackBar,
snackBar => snackBar.snacks || [] snackBar => snackBar.snacks || []
); );
export const selectBadgeNumber = createSelector(
_selectState,
state => state.badgeNumber
);

View file

@ -108,3 +108,66 @@ export const selectFileInfosPublished = createSelector(
return [...fileInfos, ...pendingFileInfos]; return [...fileInfos, ...pendingFileInfos];
} }
); );
// export const selectFileInfoForUri = (state, props) => {
// const claims = selectClaimsByUri(state),
// claim = claims[props.uri],
// fileInfos = selectAllFileInfos(state),
// outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined;
// return outpoint && fileInfos ? fileInfos[outpoint] : undefined;
// };
export const selectFileInfosByUri = createSelector(
selectClaimsByUri,
selectAllFileInfos,
(claimsByUri, byOutpoint) => {
const fileInfos = {};
const uris = Object.keys(claimsByUri);
uris.forEach(uri => {
const claim = claimsByUri[uri];
if (claim) {
const outpoint = `${claim.txid}:${claim.nout}`;
const fileInfo = byOutpoint[outpoint];
if (fileInfo) fileInfos[uri] = fileInfo;
}
});
return fileInfos;
}
);
export const selectDownloadingFileInfos = createSelector(
selectUrisDownloading,
selectFileInfosByUri,
(urisDownloading, byUri) => {
const uris = Object.keys(urisDownloading);
const fileInfos = [];
uris.forEach(uri => {
const fileInfo = byUri[uri];
if (fileInfo) fileInfos.push(fileInfo);
});
return fileInfos;
}
);
export const selectTotalDownloadProgress = createSelector(
selectDownloadingFileInfos,
fileInfos => {
const progress = [];
fileInfos.forEach(fileInfo => {
progress.push(fileInfo.written_bytes / fileInfo.total_bytes * 100);
});
const totalProgress = progress.reduce((a, b) => a + b, 0);
if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0;
else return -1;
}
);

12
ui/js/util/setBadge.js Normal file
View file

@ -0,0 +1,12 @@
const { remote } = require("electron");
const application = remote.app;
const dock = application.dock;
const win = remote.BrowserWindow.getFocusedWindow();
const setBadge = text => {
if (!dock) return;
if (win.isFocused()) return;
dock.setBadge(text);
};
export default setBadge;

View file

@ -0,0 +1,9 @@
const { remote } = require("electron");
const application = remote.app;
const win = remote.BrowserWindow.getFocusedWindow();
const setProgressBar = progress => {
win.setProgressBar(progress);
};
export default setProgressBar;