Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions kolibri/plugins/learn/assets/src/composables/useDevices.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,29 @@ export function setCurrentDevice(id) {
export default function useDevices(store) {
store = store || getCurrentInstance().proxy.$store;
const route = computed(() => store && store.state.route);
const baseurl = computed(() => {
const deviceId = computed(() => {
const params = get(route) && get(route).params;
const deviceId = params && params.deviceId;
return params && params.deviceId;
});
const baseurl = computed(() => {
const device = get(currentDevice);
if (device && device.id === deviceId) {
if (device && device.id === get(deviceId)) {
return device.base_url;
}
return;
});
const deviceName = computed(() => {
const device = get(currentDevice);
if (device && device.id === get(deviceId)) {
return device.device_name;
}
return;
});

return {
fetchDevices,
setCurrentDevice,
baseurl,
deviceName,
};
}
2 changes: 2 additions & 0 deletions kolibri/plugins/learn/assets/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ export const pageNameToModuleMap = {
[PageNames.TOPICS_TOPIC]: 'topicsTree',
[PageNames.TOPICS_TOPIC_SEARCH]: 'topicsTree',
};

export const KolibriStudioId = 'kolibri-studio';
45 changes: 36 additions & 9 deletions kolibri/plugins/learn/assets/src/modules/recommended/handlers.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { get } from '@vueuse/core';
import { ContentNodeResource } from 'kolibri.resources';
import { ContentNodeResource, RemoteChannelResource } from 'kolibri.resources';
import samePageCheckGenerator from 'kolibri.utils.samePageCheckGenerator';
import { PageNames } from '../../constants';
import { PageNames, KolibriStudioId } from '../../constants';
import useChannels from '../../composables/useChannels';
import { setCurrentDevice } from '../../composables/useDevices';
import useLearnerResources from '../../composables/useLearnerResources';
import { searchKeys } from '../../composables/useSearch';
import plugin_data from 'plugin_data';

const { channels, fetchChannels } = useChannels();

Expand Down Expand Up @@ -77,13 +78,39 @@ function _showLibrary(store, query, channels, baseurl) {
}

export function showLibrary(store, query, deviceId = null) {
if (deviceId) {
return setCurrentDevice(deviceId).then(device => {
const baseurl = device.base_url;
return fetchChannels({ baseurl }).then(channels => {
return _showLibrary(store, query, channels, baseurl);
});
/**
* ToDo: remove if block.
* Currently the channels & contentnode browser apis in studio
* are not able to load content using the the studio base url.
* Once studio is updated, this function will need to be refactored
* to use the else block code only.
*
* The if block is meant for UI viualization purposes only
* during development
*/
if (deviceId === KolibriStudioId) {
RemoteChannelResource.getKolibriStudioStatus().then(({ data }) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flagging for any other reviewers that until we have a Studio server with the new public content APIs in them, we have to do it this way.

if (data.status === 'online') {
RemoteChannelResource.fetchCollection().then(channels => {
//This is a hack to return kolibri channels.
store.commit('SET_ROOT_NODES', channels);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe I don't understand how this should work, but the result are different of what I expected:
image
The explored device has only one channel, as seen in the network request, however rootNodes is set to 10 channels that I don't know where they come from, but not from the explored device.

Copy link
Member Author

@akolson akolson Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jredrejo it looks like the current implementation within the LibraryPage returns the previously loaded library channels as the newly selected library loads. This is an issue that I think should be resolved once loading states are streamlined across the remote content browsing feature. @rtibbles any thoughts on this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, it's showing both the channels existing in the local device plus the one on the remote device.

Copy link
Member Author

@akolson akolson Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though the behavior is for previous results to be cleared once the loading is complete for remote devices. Not very sure the behavior with locally hosted devices

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the lack of the loading state is key here - especially as local channels are bootstrapped into the page so there's no loading at all.


store.commit('CORE_SET_PAGE_LOADING', false);
store.commit('CORE_SET_ERROR', null);
store.commit('SET_PAGE_NAME', PageNames.LIBRARY);
return Promise.resolve();
});
}
});
} else {
if (deviceId) {
return setCurrentDevice(deviceId).then(device => {
const baseurl = deviceId === KolibriStudioId ? plugin_data.studio_baseurl : device.base_url;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this is a naive question, but wouldn't it be possible to reuse the code from the device channel in the showAvailableChannelsPage function instead of rewritting something so similar?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultimately, we should remove most of this special casing, once we have a version of Studio that we can test against that supports the v2 public content APIs, then all we need to do is pass in the Studio baseurl, and channels and resources should all be fetched properly from Studio.

return fetchChannels({ baseurl }).then(channels => {
return _showLibrary(store, query, channels, baseurl);
});
});
}
return _showLibrary(store, query, get(channels));
}
return _showLibrary(store, query, get(channels));
}
8 changes: 6 additions & 2 deletions kolibri/plugins/learn/assets/src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function hydrateHomePage() {
});
}

const optionalDeviceIdPathSegment = '/:deviceId([a-f0-9]{32})?';
const optionalDeviceIdPathSegment = '/:deviceId([a-f0-9]{32}|kolibri-studio)?';

export default [
{
Expand Down Expand Up @@ -108,7 +108,11 @@ export default [
showLibrary(store, to.query, to.params.deviceId);
},
component: LibraryPage,
props: true,
props: route => {
return {
deviceId: route.params.deviceId,
};
},
},
{
name: PageNames.CONTENT_UNAVAILABLE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
>
<ChannelCard
:isMobile="windowIsSmall"
:title="content.title"
:title="content.title || content.name"
:thumbnail="content.thumbnail"
:tagline="getTagLine(content)"
:numCoachContents="content.num_coach_contents"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@
:layout8="{ span: 2, alignment: 'right' }"
:layout4="{ span: 4, alignment: 'right' }"
>
<KButton
<KRouterLink
appearance="raised-button"
:text="coreString('explore')"
:primary="false"
:to="libraryPageRoute"
/>
</KGridItem>
</div>
Expand Down Expand Up @@ -69,6 +70,7 @@
import commonCoreStrings from 'kolibri.coreVue.mixins.commonCoreStrings';
import useKResponsiveWindow from 'kolibri.coreVue.composables.useKResponsiveWindow';
import ChannelCard from '../ChannelCard';
import { PageNames } from '../../constants';

export default {
name: 'LibraryItem',
Expand All @@ -84,6 +86,10 @@
};
},
props: {
deviceId: {
type: String,
default: null,
},
deviceName: {
type: String,
required: false,
Expand Down Expand Up @@ -117,6 +123,16 @@
default: false,
},
},
computed: {
libraryPageRoute() {
return {
name: PageNames.LIBRARY,
params: {
deviceId: this.deviceId,
},
};
},
},
$trs: {
channels: {
message:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>

<ImmersivePage
:appBarTitle="$tr('exploreLibraries')"
:appBarTitle="learnString('exploreLibraries')"
:route="backRoute"
:primary="false"
>
Expand All @@ -18,8 +18,9 @@
</div>
<LibraryItem
v-if="showKolibriLibrary"
:key="$tr('kolibriLibrary')"
:deviceName="$tr('kolibriLibrary')"
:key="kolibriStudioId"
:deviceId="kolibriStudioId"
:deviceName="learnString('kolibriLibrary')"
deviceIcon="cloud"
:channels="kolibriLibraryChannels"
:showDescription="true"
Expand All @@ -29,6 +30,7 @@
<LibraryItem
v-for="device in pinnedDevices"
:key="device['instance_id']"
:deviceId="device['instance_id']"
:deviceName="device['device_name']"
:deviceIcon="getDeviceIcon(device)"
:channels="device.channels"
Expand All @@ -46,6 +48,7 @@
<LibraryItem
v-for="device in moreDevices"
:key="device['instance_id']"
:deviceId="device['instance_id']"
:deviceName="device['device_name']"
:deviceIcon="getDeviceIcon(device)"
:channels="device.channels"
Expand Down Expand Up @@ -73,7 +76,7 @@
import commonLearnStrings from '../commonLearnStrings';
import useChannels from '../../composables/useChannels';
import useDevices from '../../composables/useDevices';
import { PageNames } from '../../constants';
import { PageNames, KolibriStudioId } from '../../constants';
import LibraryItem from './LibraryItem';

export default {
Expand Down Expand Up @@ -117,6 +120,9 @@
this.moreDevices.length > 0 && this.moreDevices.length < this.unpinnedDevices?.length
);
},
kolibriStudioId() {
return KolibriStudioId;
},
networkDevicesWithChannels() {
return this.networkDevices.filter(device => device.channels?.length > 0);
},
Expand Down Expand Up @@ -195,10 +201,6 @@
message: 'All libraries',
context: 'A header for Explore Libraries page',
},
exploreLibraries: {
message: 'Explore libraries',
context: 'Title for Explore Libraries page',
},
showingLibraries: {
message: 'Showing libraries on other devices around you',
continue: 'Description of the kind of devices displayed',
Expand All @@ -210,14 +212,6 @@
message: 'All resources',
context: 'A filter option to show all resources',
},
kolibriLibrary: {
message: 'Kolibri Library',
context: 'Title for Kolibri Libraries',
},
libraryOf: {
message: 'Library of {device}',
context: 'A header for a device Library',
},
myDownloadsOnly: {
message: 'My downloads only',
context: 'A filter option to show only downloaded resources',
Expand Down
37 changes: 32 additions & 5 deletions kolibri/plugins/learn/assets/src/views/LearnAppBarPage.vue
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
<template>

<AppBarPage
:title="appBarTitle"
<component
:is="page"
:appBarTitle="appBarTitle"
:appearanceOverrides="appearanceOverrides"
:loading="loading"
:primary="false"
:route="route"
:title="appBarTitle"
>

<template #subNav>
<template
v-if="!deviceId"
#subNav
>
<LearnTopNav ref="topNav" />
</template>

<slot></slot>

</AppBarPage>
</component>

</template>


<script>

import AppBarPage from 'kolibri.coreVue.components.AppBarPage';
import ImmersivePage from 'kolibri.coreVue.components.ImmersivePage';
import commonCoreStrings from 'kolibri.coreVue.mixins.commonCoreStrings';
import LearnTopNav from './LearnTopNav';

export default {
name: 'LearnAppBarPage',
components: { AppBarPage, LearnTopNav },
components: {
AppBarPage,
ImmersivePage,
LearnTopNav,
},
mixins: [commonCoreStrings],
props: {
appBarTitle: {
Expand All @@ -37,10 +49,25 @@
required: false,
default: null,
},
deviceId: {
type: String,
default: null,
},
loading: {
type: Boolean,
default: null,
},
route: {
type: Object,
default() {
return {};
},
},
},
computed: {
page() {
return this.deviceId ? 'ImmersivePage' : 'AppBarPage';
},
},
};

Expand Down
Loading