Commit 37294669 authored by Martin Santangelo's avatar Martin Santangelo
Browse files

(fix) sentry subscribers report and add retry support to the list

parent 57b360e6
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -93,6 +93,7 @@ exports[`channel subscribers component should render correctly 1`] = `
    </View>
    </View>
  </View>
  </View>
  <RCTScrollView
  <RCTScrollView
    ListFooterComponent={null}
    data={
    data={
      Array [
      Array [
        Object {
        Object {
+16 −16
Original line number Original line Diff line number Diff line
@@ -134,22 +134,22 @@ class ChannelService {
      });
      });
  }
  }


  getSubscribers(guid, filter, offset) {
  /**
    const tag = `channel:subscribers:${guid}`;
   * Get subscribers
    // abort previous call
   * @param {string} guid
    abort(tag);
   * @param {string} filter
   * @param {string} offset
   */
  async getSubscribers(guid, filter, offset) {
    const data = await api.get('api/v1/subscribe/' + filter + '/' + guid, {
      offset: offset,
      limit: 12,
    });


    return api.get('api/v1/subscribe/' + filter + '/' + guid, { offset: offset, limit: 12 }, tag)
    .then((data) => {
    return {
    return {
      entities: data.users,
      entities: data.users,
      offset: data['load-next'],
      offset: data['load-next'],
        }
    };
      })
      .catch(err => {
        logService.exception('[ChannelService]', err);
        throw new Error (i18n.t('errorMessage'));
      })
  }
  }


  async getScheduledCount(guid) {
  async getScheduledCount(guid) {
+3 −1
Original line number Original line Diff line number Diff line
@@ -25,7 +25,9 @@ export default class CompleteProfile extends Component {
   * Render
   * Render
   */
   */
  render() {
  render() {
    let onboarding = featuresService.has('onboarding-december-2019') ? 'OnboardingScreenNew' : 'OnboardingScreen';
    let onboarding = featuresService.has('onboarding-december-2019')
      ? 'OnboardingScreenNew'
      : 'OnboardingScreen';
    return (
    return (
      <TouchableOpacity style={[CS.padding2x]} onPress={() => navigationService.push(onboarding)}>
      <TouchableOpacity style={[CS.padding2x]} onPress={() => navigationService.push(onboarding)}>
        <View>
        <View>
+16 −11
Original line number Original line Diff line number Diff line
@@ -27,14 +27,15 @@ import DiscoveryUser from '../../discovery/DiscoveryUser';
import CenteredLoading from '../../common/components/CenteredLoading';
import CenteredLoading from '../../common/components/CenteredLoading';
import { CommonStyle } from '../../styles/Common';
import { CommonStyle } from '../../styles/Common';
import colors from '../../styles/Colors';
import colors from '../../styles/Colors';

import ErrorLoading from '../../common/components/ErrorLoading';


/**
/**
 * Discovery screen
 * Discovery screen
 */
 */
export default
@inject('channelSubscribersStore')
@inject('channelSubscribersStore')
@observer
@observer
export default class ChannelSubscribers extends Component {
class ChannelSubscribers extends Component {


  /**
  /**
   * On component will mount
   * On component will mount
@@ -66,35 +67,40 @@ export default class ChannelSubscribers extends Component {
  render() {
  render() {
    let body;
    let body;


    const channels = this.props.channelSubscribersStore;
    const store = this.props.channelSubscribersStore;

    const footerCmp = store.errorLoading ? (
      <ErrorLoading message={i18n.t('cantLoad')} tryAgain={store.loadList} />
    ) : null;


    if (!channels.list.loaded && !channels.list.refreshing) {
    if (!store.list.loaded && !store.list.refreshing && !store.errorLoading) {
      body = <CenteredLoading />
      body = <CenteredLoading />;
    } else {
    } else {
      body = (
      body = (
        <FlatList
        <FlatList
          data={channels.list.entities.slice()}
          data={store.list.entities.slice()}
          renderItem={this.renderRow}
          renderItem={this.renderRow}
          keyExtractor={item => item.guid}
          keyExtractor={item => item.guid}
          onRefresh={this.refresh}
          onRefresh={this.refresh}
          refreshing={channels.list.refreshing}
          refreshing={store.list.refreshing}
          onEndReached={this.loadFeed}
          onEndReached={this.loadFeed}
          // onEndReachedThreshold={0}
          // onEndReachedThreshold={0}
          initialNumToRender={12}
          initialNumToRender={12}
          style={styles.listView}
          style={styles.listView}
          removeClippedSubviews={false}
          removeClippedSubviews={false}
          ListFooterComponent={footerCmp}
        />
        />
      )
      );
    }
    }


    return (
    return (
      <View style={CommonStyle.flexContainer}>
      <View style={CommonStyle.flexContainer}>
        <View style={styles.topbar}>
        <View style={styles.topbar}>
          <View style={[CommonStyle.flexContainer, CommonStyle.rowJustifyCenter]}>
          <View style={[CommonStyle.flexContainer, CommonStyle.rowJustifyCenter]}>
            <TouchableHighlight underlayColor='transparent' onPress={() => channels.setFilter('subscribers')} style={channels.filter == 'subscribers'? [styles.selectedButton, CommonStyle.flexContainerCenter]: [styles.buttons, CommonStyle.flexContainerCenter]}>
            <TouchableHighlight underlayColor='transparent' onPress={() => store.setFilter('subscribers')} style={store.filter == 'subscribers'? [styles.selectedButton, CommonStyle.flexContainerCenter]: [styles.buttons, CommonStyle.flexContainerCenter]}>
              <Text>{i18n.t('subscribers')}</Text>
              <Text>{i18n.t('subscribers')}</Text>
            </TouchableHighlight>
            </TouchableHighlight>
            <TouchableHighlight underlayColor='transparent' onPress={() => channels.setFilter('subscriptions')} style={channels.filter == 'subscriptions'? [styles.selectedButton, CommonStyle.flexContainerCenter]: [styles.buttons, CommonStyle.flexContainerCenter ]}>
            <TouchableHighlight underlayColor='transparent' onPress={() => store.setFilter('subscriptions')} style={store.filter == 'subscriptions'? [styles.selectedButton, CommonStyle.flexContainerCenter]: [styles.buttons, CommonStyle.flexContainerCenter ]}>
              <Text>{i18n.t('subscriptions')}</Text>
              <Text>{i18n.t('subscriptions')}</Text>
            </TouchableHighlight>
            </TouchableHighlight>
          </View>
          </View>
@@ -104,7 +110,6 @@ export default class ChannelSubscribers extends Component {
    );
    );
  }
  }



  /**
  /**
   * Load subs data
   * Load subs data
   */
   */
+47 −26
Original line number Original line Diff line number Diff line
import {
import { observable, action } from 'mobx';
  observable,
  action
} from 'mobx'


import OffsetListStore from '../../common/stores/OffsetListStore';
import OffsetListStore from '../../common/stores/OffsetListStore';
import channelService from '../ChannelService';
import channelService from '../ChannelService';
import UserModel from '../UserModel';
import UserModel from '../UserModel';
import logService from '../../common/services/log.service';


/**
/**
 * Subscribers Store
 * Subscribers Store
 */
 */
class ChannelSubscribersStore {
class ChannelSubscribersStore {

  list = new OffsetListStore();
  list = new OffsetListStore();

  @observable errorLoading = false;
  @observable loading = false;
  @observable filter = 'subscribers';
  @observable filter = 'subscribers';


  guid = '';
  guid = '';


  loading = false;

  setGuid(guid) {
  setGuid(guid) {
    let reload = (this.guid != guid);
    let reload = this.guid != guid;
    this.guid = guid;
    this.guid = guid;
    this.loadList(reload);
    this.loadList(reload);
  }
  }


  /**
  /**
   * Load boost list
   * Set action
   */
  @action
  setLoading(value: boolean) {
    this.loading = value;
  }

  /**
   * Set the error loading flag
   * @param {boolean} value
   */
   */
  loadList(reload = false) {
  @action
  setErrorLoading(value: boolean) {
    this.errorLoading = value;
  }


  /**
   * Load boost list
   */
  loadList = async (reload = false) => {
    if (this.list.cantLoadMore()) {
    if (this.list.cantLoadMore()) {
      return Promise.resolve();
      return Promise.resolve();
    }
    }


    if(reload)
    if (reload) {
      this.list.clearList();
      this.list.clearList();
    }


    this.loading = true;
    this.loading = true;


    return channelService.getSubscribers(this.guid, this.filter, this.list.offset)
    try {
      .then( feed => {
      this.setLoading(true);
      this.setErrorLoading(false);
      const feed = await channelService.getSubscribers(
        this.guid,
        this.filter,
        this.list.offset,
      );

      feed.entities = UserModel.createMany(feed.entities);
      feed.entities = UserModel.createMany(feed.entities);
      this.list.setList(feed);
      this.list.setList(feed);
      })
    } catch (err) {
      .finally(() => {
      this.setErrorLoading(true);
        this.loading = false;
      logService.exception(err);
      });
    } finally {
      this.setLoading(false);
    }
    }
  };


  @action
  @action
  reset() {
  reset() {
@@ -62,8 +84,7 @@ class ChannelSubscribersStore {
   */
   */
  refresh() {
  refresh() {
    this.list.refresh();
    this.list.refresh();
    this.loadList()
    this.loadList().finally(() => {
      .finally(() => {
      this.list.refreshDone();
      this.list.refreshDone();
    });
    });
  }
  }