...
 
Commits (2)
import apiService from "./api.service";
import sessionService from "./session.service";
import entitiesService from "./entities.service";
import blockListService from "./block-list.service";
import BoostedContentSync from "../../lib/minds-sync/services/BoostedContentSync";
import sqliteStorageProviderService from "./sqlite-storage-provider.service";
import hashCode from "../helpers/hash-code";
class BoostedContentService {
initialized = false;
constructor() {
const storageAdapter = sqliteStorageProviderService.get();
this.sync = new BoostedContentSync(apiService, storageAdapter, 5 * 60, 15 * 60, 500);
this.sync.setResolvers({
currentUser: () => sessionService.guid,
blockedUserGuids: async () => await blockListService.getList(),
fetchEntities: async guids => await entitiesService.fetch(guids),
});
this.sync.setUp();
sessionService.onSession((is) => {
if (is) {
this.initialized = true;
// UNCOMMENT!
this.sync.setRating(2);
// this.sync.setRating(sessionService.getUser().boost_rating || null);
} else {
if (this.initialized) {
this.sync.destroy();
}
}
});
setTimeout(() => {
this.gc();
}, 60000);
}
async get(opts) {
return await this.sync.get(opts);
}
async fetch(opts) {
return await this.sync.fetch(opts);
}
async gc(opts) {
return await this.sync.gc(opts);
}
}
export default new BoostedContentService();
......@@ -3,6 +3,7 @@ import apiService from "./api.service";
import sqliteStorageProviderService from "./sqlite-storage-provider.service";
import { Alert } from "react-native";
import logService from "./log.service";
import normalizeUrn from "../helpers/normalize-urn";
class EntitiesService {
constructor() {
......@@ -36,7 +37,7 @@ class EntitiesService {
return [];
}
const urns = guids.map(guid => `urn:entity:${guid}`);
const urns = guids.map(guid => normalizeUrn(guid));
return await this.sync.get(urns);
}
......@@ -46,7 +47,7 @@ class EntitiesService {
return true;
}
const urns = guids.map(guid => `urn:entity:${guid}`);
const urns = guids.map(guid => normalizeUrn(guid));
return await this.sync.sync(urns);
}
......
......@@ -69,6 +69,7 @@ class LogService {
}
if (stack) {
deviceLog.rnerror(false, (prepend ? `${prepend} ` : '') + error.message, stack);
if (__DEV__) console.log(error);
} else {
deviceLog.error((prepend ? `${prepend} ` : '') + String(error));
}
......
......@@ -14,6 +14,8 @@ import GroupModel from '../groups/GroupModel';
import NewsfeedFilterStore from '../common/stores/NewsfeedFilterStore';
import DiscoveryFeedStore from './DiscoveryFeedStore';
import logService from '../common/services/log.service';
import featuresService from '../common/services/features.service';
import boostedContentService from '../common/services/boosted-content.service';
/**
* Discovery Store
......@@ -165,6 +167,12 @@ class DiscoveryStore {
// if the filter has changed during the call we ignore the results
if (filter === this.filters.filter) {
// inject boosts
if (type === 'activities' && featuresService.has('es-feeds')) {
await this.injectBoosts(feed, store.list);
}
this.createModels(type, feed, preloadImage);
this.assignRowKeys(feed);
store.list.setList(feed, refresh);
......@@ -175,7 +183,7 @@ class DiscoveryStore {
return;
}
if (!(typeof err === 'TypeError' && err.message === 'Network request failed')) {
logService.exception('[DiscoveryStore]', err);
logService.exception('[DiscoveryStore] loadList', err);
}
store.list.setErrorLoading(true);
} finally {
......@@ -183,6 +191,43 @@ class DiscoveryStore {
}
}
/**
* Inject boosts to the feed
* @param {object} feed
* @param {OffsetFeedListStore} list
*/
async injectBoosts(feed, list) {
const start = list.entities.length;
const finish = feed.entities.length + start;
if (finish > 40) return;
await this.insertBoost(3, feed, start, finish);
await this.insertBoost(8, feed, start, finish);
await this.insertBoost(16, feed, start, finish);
await this.insertBoost(24, feed, start, finish);
await this.insertBoost(32, feed, start, finish);
await this.insertBoost(40, feed, start, finish);
}
/**
* Insert a boost in give position
* @param {integer} position
* @param {object} feed
* @param {integer} start
* @param {integer} finish
*/
async insertBoost(position, feed, start, finish) {
if (start <= position && finish >= position) {
try {
const boost = await boostedContentService.fetch();
if (boost) feed.entities.splice( position + start, 0, boost );
} catch (err) {
logService.exception('[DiscoveryStore] insertBoost', err);
}
}
}
/**
* Generate a unique Id for use with list views
* @param {object} feed
......
......@@ -39,8 +39,8 @@ export default class BoostedContentSync {
this.db.schema(2.1, {
boosts: {
primaryKey: 'urn',
indexes: ['sync', 'lastImpression', 'owner_guid'],
fields: ['impressions'],
fields:['impressions'],
indexes: ['sync', 'lastImpression', 'owner_guid']
},
});
......@@ -200,7 +200,7 @@ export default class BoostedContentSync {
return await this.resolvers.fetchEntities(dataSet.map(row => row.urn));
} catch (e) {
console.error('BoostedContentSync.fetch', e);
console.log('BoostedContentSync.fetch', e);
// Release locks
......@@ -296,7 +296,7 @@ export default class BoostedContentSync {
this.db
.deleteLessThan('boosts', 'sync', Date.now() - this.stale_after_ms);
} catch (e) {
console.error('BoostedContentSync.pruneStaleBoosts', e);
console.log('BoostedContentSync.pruneStaleBoosts', e);
throw e;
}
}
......@@ -313,7 +313,7 @@ export default class BoostedContentSync {
return true;
} catch (e) {
console.error('BoostedContentSync.prune', e);
console.log('BoostedContentSync.prune', e);
throw e;
}
}
......@@ -331,7 +331,7 @@ export default class BoostedContentSync {
return true;
} catch (e) {
console.error('BoostedContentSync.destroy', e);
console.log('BoostedContentSync.destroy', e);
throw e;
}
}
......
......@@ -5,6 +5,8 @@ import NewsfeedService, { setViewed } from './NewsfeedService';
import OffsetFeedListStore from '../common/stores/OffsetFeedListStore';
import ActivityModel from './ActivityModel';
import logService from '../common/services/log.service';
import boostedContentService from '../common/services/boosted-content.service';
import featuresService from '../common/services/features.service';
/**
* News feed store
......@@ -71,6 +73,11 @@ class NewsfeedStore {
try {
feed = await fetchFn(store.list.offset, 12);
// inject boosts
if (featuresService.has('es-feeds')) {
await this.injectBoosts(feed);
}
feed.entities = ActivityModel.createMany(feed.entities);
this.assignRowKeys(feed, store);
store.list.setList(feed, refresh);
......@@ -82,13 +89,49 @@ class NewsfeedStore {
store.list.setErrorLoading(true);
if (!(typeof err === 'TypeError' && err.message === 'Network request failed')) {
logService.exception('[NewsfeedStore]', err);
logService.exception('[NewsfeedStore] loadFeed', err);
}
} finally {
store.loading = false;
}
}
/**
* Inject boosts to the feed
* @param {object} feed
*/
async injectBoosts(feed) {
const start = this.list.entities.length;
const finish = feed.entities.length + start;
if (finish > 40) return;
await this.insertBoost(3, feed, start, finish);
await this.insertBoost(8, feed, start, finish);
await this.insertBoost(16, feed, start, finish);
await this.insertBoost(24, feed, start, finish);
await this.insertBoost(32, feed, start, finish);
await this.insertBoost(40, feed, start, finish);
}
/**
* Insert a boost in give position
* @param {integer} position
* @param {object} feed
* @param {integer} start
* @param {integer} finish
*/
async insertBoost(position, feed, start, finish) {
if (start <= position && finish >= position) {
try {
const boost = await boostedContentService.fetch();
if (boost) feed.entities.splice( position + start, 0, boost );
} catch (err) {
logService.exception('[NewsfeedStore] insertBoost', err);
}
}
}
/**
* Generate a unique Id for use with list views
* @param {object} feed
......