Skip to content

Commit

Permalink
Merge pull request #11177 from marcellamaki/my-downloads-polling-ui-u…
Browse files Browse the repository at this point in the history
…pdates

My downloads updates - polling and UI
  • Loading branch information
rtibbles authored Oct 10, 2023
2 parents da0cba2 + a2d6ab7 commit 886f50f
Show file tree
Hide file tree
Showing 17 changed files with 503 additions and 273 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@
* ```
*/

import { ref } from 'kolibri.lib.vueCompositionApi';

const MOCK_DEFAULTS = {
fetchDevices: jest.fn(() => Promise.resolve([])),
baseurl: null,
networkDevices: ref({}),
};

export function useDevicesMock(overrides = {}) {
Expand All @@ -43,6 +46,14 @@ export function useDevicesMock(overrides = {}) {
};
}

const DEVICE_DATA_DEFAULTS = {
baseurl: 'http://test-device',
deviceName: 'test-device',
instanceId: '1234',
};

export const currentDeviceData = jest.fn(() => DEVICE_DATA_DEFAULTS);

export default jest.fn(() => useDevicesMock());

export const setCurrentDevice = jest.fn(id =>
Expand Down
39 changes: 36 additions & 3 deletions kolibri/plugins/learn/assets/src/composables/useDevices.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
* A composable function containing logic related to channels
*/

import { computed, getCurrentInstance, ref } from 'kolibri.lib.vueCompositionApi';
import { computed, getCurrentInstance, ref, onBeforeUnmount } from 'kolibri.lib.vueCompositionApi';
import { NetworkLocationResource, RemoteChannelResource } from 'kolibri.resources';
import { get, set } from '@vueuse/core';
import { get, set, useTimeoutPoll } from '@vueuse/core';
import useMinimumKolibriVersion from 'kolibri.coreVue.composables.useMinimumKolibriVersion';
import useUser from 'kolibri.coreVue.composables.useUser';
import plugin_data from 'plugin_data';
Expand Down Expand Up @@ -86,7 +86,7 @@ function computedDevice(routingDeviceId, callback) {
});
}

export default function useDevices(store) {
export function currentDeviceData(store) {
store = store || getCurrentInstance().proxy.$store;
const route = computed(() => store && store.state.route);
const routingDeviceId = computed(() => {
Expand All @@ -98,11 +98,44 @@ export default function useDevices(store) {
const baseurl = computedDevice(routingDeviceId, device => device.base_url);
const deviceName = computedDevice(routingDeviceId, device => device.device_name);

return {
instanceId,
baseurl,
deviceName,
};
}

export default function useDevices(store) {
const networkDevices = ref({});
const isLoading = ref(false);
const { instanceId, baseurl, deviceName } = currentDeviceData(store);

async function setNetworkDevices() {
isLoading.value = true;
const newNetworkDevices = {};
const devices = await fetchDevices();
for (const device of devices) {
newNetworkDevices[device.instance_id] = device;
}
networkDevices.value = newNetworkDevices;
isLoading.value = false;
}

// Start polling
const fetch = useTimeoutPoll(setNetworkDevices, 5000, { immediate: true });

// Stop polling
onBeforeUnmount(() => {
fetch.pause();
});

return {
fetchDevices,
isLoading,
setCurrentDevice,
instanceId,
baseurl,
deviceName,
networkDevices,
};
}
38 changes: 22 additions & 16 deletions kolibri/plugins/learn/assets/src/composables/useDownloadRequests.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import redirectBrowser from 'kolibri.utils.redirectBrowser';
import urls from 'kolibri.urls';
import client from 'kolibri.client';
import Vue from 'kolibri.lib.vue';
import useDevices from './useDevices';
import { currentDeviceData } from '../composables/useDevices';

const downloadRequestsTranslator = createTranslator('DownloadRequests', {
downloadStartedLabel: {
Expand All @@ -35,17 +35,24 @@ const availableSpace = ref(0);
export default function useDownloadRequests(store) {
store = store || getCurrentInstance().proxy.$store;

const { instanceId } = useDevices(store);
const { instanceId } = currentDeviceData(store);

function fetchUserDownloadRequests(params) {
return ContentRequestResource.list(params)
.then(downloadRequests => {
if (downloadRequests.results) {
downloadRequests = downloadRequests.results;
}
for (const obj of downloadRequests) {
set(downloadRequestMap, obj.id, obj);
set(downloadRequestMap, obj.contentnode_id, obj);
}
set(loading, false);
return downloadRequests;
})
.then(store.dispatch('notLoading'));
.then(downloadRequests => {
store.dispatch('notLoading');
return downloadRequests;
});
}

function fetchAvailableFreespace() {
Expand All @@ -67,14 +74,14 @@ export default function useDownloadRequests(store) {
redirectBrowser(urls['kolibri:kolibri.plugins.learn:my_downloads']());
}

function addDownloadRequest(content) {
function addDownloadRequest(contentNode) {
const metadata = {
title: content.title,
file_size: content.files.reduce((size, f) => size + f.file_size, 0),
learning_activities: content.learning_activities,
title: contentNode.title,
file_size: contentNode.files.reduce((size, f) => size + f.file_size, 0),
learning_activities: contentNode.learning_activities,
};
const data = {
contentnode_id: content.id,
contentnode_id: contentNode.id,
metadata,
source_id: store.getters.currentUserId,
source_instance_id: get(instanceId),
Expand All @@ -84,7 +91,7 @@ export default function useDownloadRequests(store) {
date_added: new Date(),
};
ContentRequestResource.create(data).then(downloadRequest => {
set(downloadRequestMap, downloadRequest.node_id, downloadRequest);
set(downloadRequestMap, downloadRequest.contentnode_id, downloadRequest);
});

store.commit('CORE_CREATE_SNACKBAR', {
Expand All @@ -98,28 +105,27 @@ export default function useDownloadRequests(store) {
return Promise.resolve();
}

function removeDownloadRequest(content) {
function removeDownloadRequest(contentRequest) {
ContentRequestResource.deleteModel({
id: content.id,
contentnode_id: content.contentnode_id,
id: contentRequest.id,
});
Vue.delete(downloadRequestMap, content.id);
Vue.delete(downloadRequestMap, contentRequest.contentnode_id);
return Promise.resolve();
}

function isDownloadingByLearner(content) {
if (!content || !content.id) {
return false;
}
const downloadRequest = downloadRequestMap[this.content.id];
const downloadRequest = downloadRequestMap[content.id];
return Boolean(downloadRequest && !downloadRequest.status === 'COMPLETED');
}

function isDownloadedByLearner(content) {
if (!content || !content.id) {
return false;
}
const downloadRequest = downloadRequestMap[this.content.id];
const downloadRequest = downloadRequestMap[content.id];
return Boolean(downloadRequest && downloadRequest.status === 'COMPLETED');
}

Expand Down
4 changes: 2 additions & 2 deletions kolibri/plugins/learn/assets/src/composables/useSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import {
ResourcesNeededTypes,
} from 'kolibri.coreVue.vuex.constants';
import { deduplicateResources } from '../utils/contentNode';
import { currentDeviceData } from './useDevices';
import useContentNodeProgress from './useContentNodeProgress';
import useDevices from './useDevices';
import { setLanguages } from './useLanguages';

export const logging = logger.getLogger(__filename);
Expand Down Expand Up @@ -158,7 +158,7 @@ export default function useSearch(descendant, store, router) {
const more = ref(null);
const labels = ref(null);

const { baseurl } = useDevices(store);
const { baseurl } = currentDeviceData(store);

const searchTerms = computed({
get() {
Expand Down
Loading

0 comments on commit 886f50f

Please sign in to comment.