Facebook
From Crippled Tern, 1 Year ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 115
  1. import React from 'react';
  2. import { ScrollView, FlatList, Platform, Text, View, Dimensions, TouchableOpacity, Share } from 'react-native';
  3. import { SafeAreaView } from 'react-native-safe-area-context';
  4. import styles from '../styles/Collections';
  5. import drawerStyles from '../styles/DrawerMenu';
  6. import CustomIcons from '../components/CustomIcon';
  7. import CustomAlert from '../components/CustomAlert';
  8. import ActionSheet from '../components/ActionSheet';
  9. import EmptyScreen from '../components/EmptyScreen';
  10. import Chip from '../components/Chip';
  11. import { moderateScale } from '../utils/Scaling';
  12. import EStyleSheet from 'react-native-extended-stylesheet';
  13. import * as colProvider from '../utils/ColProvider';
  14. import * as apiProvider from '../utils/ApiProvider';
  15. import * as varProvider from '../utils/VarProvider';
  16. import * as analyticsProvider from '../utils/AnalyticsProvider';
  17. import * as setProvider from '../utils/SetProvider';
  18. import * as notProvider from '../utils/NotProvider';
  19. import screenNames from '../config/screenNames';
  20. import * as connection from '../utils/Connection';
  21. import config from '../config/config';
  22. import DrawerLayout from 'react-native-drawer-layout';
  23. import { translate } from '../locales/i18n';
  24. import Spinner from 'react-native-spinkit';
  25. import RNFetchBlob from 'rn-fetch-blob';
  26. import * as MD5 from '../utils/MD5';
  27. import humanize from 'tiny-human-time';
  28. import Toast from '@remobile/react-native-toast';
  29. import MVMyloftPDFViewerNativeModuleIos from '../components/MVMyloftPDFViewerNativeModule.ios';
  30. import ArticleLoader from '../components/ArticleLoader';
  31. // import ArticleListView from '../components/ArticleListView';
  32.  
  33. import ArticleListNewView from '../components/ArticleList/index';
  34. import ArticleCardNewView from '../components/ArticleCard/index';
  35. import LinearGradient from 'react-native-linear-gradient';
  36. import ShareIntentModule from '../components/ShareIntentModule';
  37. import ShareActionSheet from '../components/ShareActionSheet';
  38. import AsyncStorage from '@react-native-async-storage/async-storage';
  39. import staticConfig from '../config/staticConfig';
  40. import imageJson from '../config/imageJson';
  41. import guideImageJson from '../config/guideImageJson';
  42. import GuideView from '../components/GuideView';
  43. import TagBottomSheet from '../components/TagBottomSheet';
  44.  
  45. var asList, articleList, collectionList, filteredColList, tagList, imagePath, title, text, isLink, links;
  46.  
  47. var cloneIt, cardWidth, numberOfCards, modalWidth, modalHeight, cardLeftWidth, closeFlag;
  48.  
  49. var noMoreData, isFirstTime, alreadyLoaded, alreadySubscribed, isInfiniteOn, graphError;
  50. var pagingCount = config.articlePagingCount, screenWidth, isEditMode, drawerLockMode, startParentResponderTouch = true, startChildResponderTouch, modalObserver;
  51.  
  52. //need for showing favorite articles in side menu
  53. var favoriteArticles = {
  54.   "id": "favoriteArticles",
  55.   "title": translate("FAVORITE_ARTICLES"),
  56.   "description": "",
  57.   "isDefault": false,
  58.   "active": false
  59. };
  60.  
  61. export default class Collections extends React.Component {
  62.  
  63.   constructor(props) {
  64.     super(props);
  65.  
  66.     this.state = {
  67.       isCardView: varProvider.isCardView,
  68.       modalVisible: false,
  69.       articleList: [],
  70.       articleLoading: true,
  71.       articleLength: 0,
  72.       footerLoading: false,
  73.       errorLoading: false,
  74.       deleteModal: false,
  75.       asList: [],
  76.       activeFilters: [],
  77.       refreshCollection: false,
  78.       loadHint: false,
  79.       articleType: "",
  80.       showGuide: false
  81.     };
  82.     graphError = "";
  83.     isEditMode = false;
  84.     drawerLockMode = "unlocked";
  85.     collectionList = [];
  86.     filteredColList = [];
  87.     articleList = [];
  88.     tagList = [];
  89.     modalHeight = null;
  90.     alreadyLoaded = true;
  91.     isInfiniteOn = false;
  92.     if (varProvider.selectedCollectionName == undefined) {
  93.       varProvider.selectedCollectionName = "";
  94.     }
  95.  
  96.     AsyncStorage.getItem("articleTimestamp").then((value) => {
  97.       if (!value) {
  98.         isFirstTime = true;
  99.       }
  100.     });
  101.  
  102.     //this function is here because it just creates array for action sheet
  103.     this.initActionSheetList();
  104.  
  105.     this.openMenu = this.openMenu.bind(this);
  106.     this.closeEditTitleModal = this.closeEditTitleModal.bind(this);
  107.     this.closeDeleteArticleModal = this.closeDeleteArticleModal.bind(this);
  108.     this.getEditTitleText = this.getEditTitleText.bind(this);
  109.     this.onSaveEditTitle = this.onSaveEditTitle.bind(this);
  110.     this.onDeleteArticle = this.onDeleteArticle.bind(this);
  111.     this.onOpenWithExternalView = this.onOpenWithExternalView.bind(this);
  112.     this.closeActionSheetModal = this.closeActionSheetModal.bind(this);
  113.     this.hideActionSheetModal = this.hideActionSheetModal.bind(this);
  114.     this.callbackFun = this.callbackFun.bind(this);
  115.     this.openArticleView = this.openArticleView.bind(this);
  116.     this.callbackAddTag = this.callbackAddTag.bind(this);
  117.     this.callbackDeleteArticle = this.callbackDeleteArticle.bind(this);
  118.     this.callbackRead = this.callbackRead.bind(this);
  119.     this.buttonCallback = this.buttonCallback.bind(this);
  120.     this.setDefaultCollection = this.setDefaultCollection.bind(this);
  121.     this.closeAddCollectionModal = this.closeAddCollectionModal.bind(this);
  122.     this.onSaveAddCollection = this.onSaveAddCollection.bind(this);
  123.     this.getAddCollectionText = this.getAddCollectionText.bind(this);
  124.     this.closeEditTitleCollectionModal = this.closeEditTitleCollectionModal.bind(this);
  125.     this.getEditTitleCollectionText = this.getEditTitleCollectionText.bind(this);
  126.     this.onSaveEditTitleCollection = this.onSaveEditTitleCollection.bind(this);
  127.     this.closeDeleteCollectionModal = this.closeDeleteCollectionModal.bind(this);
  128.     this.onDeleteCollection = this.onDeleteCollection.bind(this);
  129.     this.closeEditMode = this.closeEditMode.bind(this);
  130.     this.selectColAndLoadArticle = this.selectColAndLoadArticle.bind(this);
  131.     this.startArticleSubscription = this.startArticleSubscription.bind(this);
  132.     this.startCollectionSubscription = this.startCollectionSubscription.bind(this);
  133.     this.favoriteArticle = this.favoriteArticle.bind(this);
  134.     this.openModal = this.openModal.bind(this);
  135.     this.initMaxHeight = this.initMaxHeight.bind(this);
  136.   }
  137.  
  138.   static navigationOptions = () => {
  139.     return {
  140.       headerShown: false
  141.     }
  142.   }
  143.  
  144.   componentDidMount() {
  145.     varProvider.currentScreen = screenNames.Collections;
  146.     this.loadCollectionList();
  147.     this.startCollectionSubscription();
  148.     this.startArticleSubscription();
  149.  
  150.     this.initMaxHeight();
  151.     Dimensions.addEventListener("change", this.initMaxHeight);
  152.  
  153.     setProvider.showGuide("isCollectionsGuideShown", screenNames.Collections).then((res) => {
  154.       if (res) {
  155.         this.setState({ showGuide: true });
  156.       }
  157.     })
  158.  
  159.     varProvider.connectionObserver.subscribe(() => {
  160.       asList[1].isGrayedOut = connection.isConnectedFun() ? false : true
  161.       this.setState({
  162.         isConnected: connection.isConnectedFun(),
  163.         asList: asList,
  164.       });
  165.     });
  166.     modalObserver = varProvider.modalClosedObserver.subscribe((data) => {
  167.       if (varProvider.currentScreen === screenNames.Collections && data.other) {
  168.         if (this.state.actionSheetModal || this.state.sharedOpened || this.state.editTitleModal || this.state.deleteArticleModal || this.state.addCollectionModal || this.state.deleteCollectionModal || this.state.editTitleCollectionModal || this.state.showGuide) {
  169.           this.setState({
  170.             actionSheetModal: false,
  171.             sharedOpened: false,
  172.             editTitleModal: false,
  173.             deleteArticleModal: false,
  174.             addCollectionModal: false,
  175.             deleteCollectionModal: false,
  176.             editTitleCollectionModal: false,
  177.             showGuide: false,
  178.           });
  179.         }
  180.         if (varProvider.modalClosedObserver) {
  181.           let resJson = {
  182.             "home": true,
  183.             "other": false,
  184.             "screen": screenNames.Collections,
  185.           }
  186.           varProvider.modalClosedObserver.next(resJson);
  187.         }
  188.       }
  189.     });
  190.     this._unsubscribe = this.props.navigation.addListener('focus', () => {
  191.       this.isFocused();
  192.     });
  193.     //this is used for showing and hiding collection hint
  194.     AsyncStorage.getItem("isFirstTime").then((value) => {
  195.       if (value != "false")
  196.         this.setState({ loadHint: true })
  197.     })
  198.   }
  199.  
  200.   componentWillUnmount() {
  201.     this._unsubscribe();
  202.     modalObserver.unsubscribe();
  203.   }
  204.  
  205.   isFocused() {
  206.     const { params } = this.props.route;
  207.     if (params) {
  208.       var isSearchText = false;
  209.       // [deep link] if collectionId is received from params, then set it as a selected collection to load articles of that collection
  210.       if (params.collectionId) {
  211.         varProvider.selectedCollectionId = params.collectionId;
  212.       }
  213.       // [deep link] if collectionId is "favoriteArticles", then load favorite articles
  214.       if (varProvider.selectedCollectionId == "favoriteArticles") {
  215.         varProvider.selectedCollectionName = favoriteArticles.title;
  216.         favoriteArticles.active = true;
  217.       }
  218.  
  219.       // [deep link] if searchText is received from params, then set it as a active filter and load article list accordingly
  220.       if (params.searchText) {
  221.         isSearchText = true;
  222.         let originalSearchText = params.searchText;
  223.         let trimmedSearchText = originalSearchText.trim();
  224.         var filterJson = [
  225.           {
  226.             "active": false,
  227.             "chipTitle": "",
  228.             "value": "",
  229.             "originalSearchText": ""
  230.           },
  231.           {
  232.             "active": false,
  233.             "chipTitle": "",
  234.             "value": "",
  235.             "originalSearchText": ""
  236.           },
  237.           {
  238.             "active": false,
  239.             "chipTitle": "",
  240.             "value": "",
  241.             "originalSearchText": ""
  242.           },
  243.           {
  244.             "active": false,
  245.             "chipTitle": "",
  246.             "value": "",
  247.             "originalSearchText": ""
  248.           },
  249.           {
  250.             "active": false,
  251.             "chipTitle": "",
  252.             "value": "",
  253.             "originalSearchText": ""
  254.           },
  255.           {
  256.             "active": true,
  257.             "chipTitle": 'Search text: "' + originalSearchText + '"',
  258.             "value": trimmedSearchText,
  259.             "originalSearchText": originalSearchText
  260.           }
  261.         ];
  262.         this.setState({
  263.           isFilter: true,
  264.           activeFilters: filterJson
  265.         });
  266.       }
  267.  
  268.       params.contentType = "";
  269.       params.searchText = "";
  270.     }
  271.  
  272.     varProvider.currentScreen = screenNames.Collections;
  273.     if (varProvider.isCollectionTabChanged) {
  274.       varProvider.isCollectionTabChanged = false;
  275.       if (varProvider.fromBroswerView) {
  276.         for (var i = 0; i < collectionList.length; i++) {
  277.           if (varProvider.selectedCollectionId == collectionList[i].id) {
  278.             collectionList[i].active = true;
  279.           }
  280.           else {
  281.             collectionList[i].active = false;
  282.           }
  283.         }
  284.         varProvider.fromBroswerView = false;
  285.         this.setState({ refreshCollection: !this.state.refreshCollection });
  286.       }
  287.       //don't call when component will mount called
  288.       if (!alreadyLoaded) {
  289.         // [deep link] get collection item based on received collectionId from params
  290.         let activeCollectionItem;
  291.         if (varProvider.selectedCollectionId == "favoriteArticles") {
  292.           activeCollectionItem = favoriteArticles;
  293.         } else {
  294.           for (var i = 0; i < collectionList.length; i++) {
  295.             if (collectionList[i].id == varProvider.selectedCollectionId) {
  296.               activeCollectionItem = collectionList[i];
  297.               break;
  298.             }
  299.           }
  300.         }
  301.         if (activeCollectionItem) {
  302.           if (!isSearchText) {
  303.             // [deep link] if searchText is not received than first disable all active filter
  304.             var tempFilters = this.state.activeFilters;
  305.             for (var i = 0; i < tempFilters.length; i++) {
  306.               tempFilters[i].active = false;
  307.             }
  308.           }
  309.           // [deep link] below method is for loading the article list of specific collection
  310.           this.menuItemPress(activeCollectionItem);
  311.         } else {
  312.           if (!this.state.isFilter) {
  313.             //no filters is applied, so reload the article list by updated timestamp from sqlite
  314.             var lastArticleTimestamp;
  315.             var artLength = articleList.length;
  316.             if (artLength != 0) {
  317.               lastArticleTimestamp = articleList[artLength - 1].createdAt;
  318.             }
  319.  
  320.             var tempJson = {
  321.               "limit": pagingCount,
  322.               "offset": 0
  323.             };
  324.             if (artLength > pagingCount) {
  325.               tempJson["lastTimestamp"] = lastArticleTimestamp;
  326.             }
  327.             this.loadSyncedSql(tempJson);
  328.  
  329.             //sync article list when switching between tabs
  330.             if (!varProvider.isSyncInProgress) {
  331.               colProvider.getSyncArticles(0);
  332.             }
  333.           } else {
  334.             //TO DO: filter is applied
  335.           }
  336.         }
  337.       }
  338.  
  339.       let screenViewJson = {
  340.         "name": screenNames.Collections,
  341.         "previous": varProvider.lastTabName
  342.       };
  343.       analyticsProvider.logAnalyticsJson("ScreenView", screenViewJson);
  344.       varProvider.lastTabName = screenNames.Collections;
  345.     }
  346.  
  347.     alreadyLoaded = false;
  348.   }
  349.  
  350.   _handleOpenURL(event) {
  351.     // console.log("collection handle open url");
  352.     // console.log(event.url);
  353.     //parse and check if url is welcome mail url or shared url
  354.     //if welcome mail then navigate to screen with option to logout from current account and login to new account
  355.     //if shared url then navigate to browser
  356.   }
  357.  
  358.   initActionSheetList() {
  359.     asList = [
  360.       {
  361.         title: translate("FILE_DOWNLOAD_OPEN"),
  362.         icon: "icon_open_with",
  363.         isVisible: true,
  364.         isGrayedOut: false,
  365.         onPressFun: this.onOpenWithExternalView.bind(this)
  366.       },
  367.       {
  368.         title: translate("SHARE"),
  369.         icon: Platform.OS == "ios" ? "icon_share_ios" : "icon_share",
  370.         isVisible: true,
  371.         isGrayedOut: false,
  372.         onPressFun: this.shareArticle.bind(this)
  373.       },
  374.       {
  375.         title: translate("ADD_TAGS"),
  376.         icon: "icon_add_tag",
  377.         isVisible: true,
  378.         isGrayedOut: false,
  379.         onPressFun: this.addTags.bind(this)
  380.       },
  381.       {
  382.         title: translate("EDIT_TITLE"),
  383.         icon: "icon_edit",
  384.         isVisible: true,
  385.         isGrayedOut: false,
  386.         onPressFun: this.editTitleArticle.bind(this)
  387.       },
  388.       {
  389.         title: translate("MOVE_TO_COLLECTION"),
  390.         icon: "icon_move",
  391.         isVisible: true,
  392.         isGrayedOut: false,
  393.         onPressFun: this.moveToCollection.bind(this)
  394.       },
  395.       {
  396.         title: translate("DELETE"),
  397.         icon: "icon_delete",
  398.         isVisible: true,
  399.         isGrayedOut: false,
  400.         onPressFun: this.deleteArticle.bind(this)
  401.       },
  402.       {
  403.         title: translate("MARK_AS") + translate("UNREAD"),
  404.         icon: "icon_visible",
  405.         isVisible: true,
  406.         isGrayedOut: false,
  407.         onPressFun: this.markAsRead.bind(this)
  408.       },
  409.     ]
  410.   }
  411.  
  412.   //initially load the collection list from sqlite
  413.   loadCollectionList() {
  414.     colProvider.getCollectionSql().then((data) => {
  415.       // console.log(data);
  416.       this.processCollectionList(data);
  417.       this.loadArticleList();
  418.     });
  419.  
  420.     //whenever sync process will finish it will fetch collections from api
  421.     //we will get the fetched data in subscribe section
  422.     varProvider.collectionObservable.subscribe((data) => {
  423.       // console.log("collection observable get data");
  424.       // console.log(data)
  425.       if (data.isSetColId) {
  426.         if (data.data) {
  427.           for (var j = 0; j < collectionList.length; j++) {
  428.             if (collectionList[j].title === data.data.title) {
  429.               collectionList[j].id = data.data.id
  430.               break
  431.             }
  432.           }
  433.         }
  434.       }
  435.       else {
  436.         this.processCollectionList(data.data);
  437.       }
  438.     });
  439.   }
  440.  
  441.   processCollectionList(data) {
  442.     collectionList = [];
  443.     var isActive;
  444.     for (var i = 0; i < data.length; i++) {
  445.       // [deep link] get collection name of selected collection and set it as active based on params
  446.       if (varProvider.selectedCollectionId == data[i].id) {
  447.         varProvider.selectedCollectionName = data[i].title;
  448.         isActive = true;
  449.       }
  450.       isActive = (varProvider.selectedCollectionName == data[i].title);
  451.       if (data[i].isDefault == 1 && data[i].title == "General Collection")
  452.         isFirstTime = false;
  453.       if (data[i].isDefault == 1) {
  454.         varProvider.defaultCollectionId = data[i].id;
  455.         varProvider.defaultCollectionName = data[i].title;
  456.         varProvider.defaultCollectionType = data[i].type;
  457.         if (!varProvider.selectedCollectionName && !varProvider.selectedCollectionId) {
  458.           varProvider.selectedCollectionId = data[i].id;
  459.           varProvider.selectedCollectionName = data[i].title;
  460.           isActive = true;
  461.         }
  462.         AsyncStorage.multiSet([
  463.           ["defaultCollectionId", varProvider.defaultCollectionId],
  464.           ["defaultCollectionName", varProvider.defaultCollectionName],
  465.           ["defaultCollectionType", varProvider.defaultCollectionType]
  466.         ]);
  467.  
  468.         //collection marked as default should be on top so used unshift instead of push
  469.         collectionList.unshift({
  470.           "id": data[i].id,
  471.           "title": data[i].title,
  472.           "description": data[i].description,
  473.           "isDefault": data[i].isDefault == 1 ? true : false,
  474.           "type": data[i].type,
  475.           "createdAt": data[i].createdAt,
  476.           "updatedAt": data[i].updatedAt,
  477.           "pressed": false,
  478.           "active": isActive,
  479.         });
  480.       }
  481.       else {
  482.         collectionList.push({
  483.           "id": data[i].id,
  484.           "title": data[i].title,
  485.           "description": data[i].description,
  486.           "isDefault": data[i].isDefault == 1 ? true : false,
  487.           "type": data[i].type,
  488.           "createdAt": data[i].createdAt,
  489.           "updatedAt": data[i].updatedAt,
  490.           "pressed": false,
  491.           "active": isActive,
  492.         });
  493.       }
  494.     }
  495.     // console.log(collectionList);
  496.     filteredColList = collectionList;
  497.     this.setState({ refreshCollection: !this.state.refreshCollection });
  498.   }
  499.  
  500.   loadArticleList() {
  501.     // console.log("load article list init");
  502.     noMoreData = false;
  503.     colProvider.getArticleList().then((data) => {
  504.       // console.log(data);
  505.       articleList = [];
  506.       if (data.length != 0) {
  507.         this.processArticleList(data, 0);
  508.       }
  509.       else {
  510.         //no article in local db
  511.         if (!isFirstTime) {
  512.           this.setState({ refresh: !this.state.refresh, articleLoading: false, articleLength: articleList.length });
  513.         }
  514.       }
  515.  
  516.       // [deep link] if filter is active then again load the article list
  517.       if (this.state.isFilter) {
  518.         this.callbackFun(this.state.activeFilters);
  519.       }
  520.     });
  521.  
  522.     //subscribe to article observable if not subscribed
  523.     if (!alreadySubscribed) {
  524.       alreadySubscribed = true;
  525.       //whenever article list gets fetched, here we get the response
  526.       varProvider.articleObserver.subscribe((resJson) => {
  527.         // console.log("article observable get data");
  528.         // console.log(resJson);
  529.  
  530.         if (!resJson.error) {
  531.           if (!resJson.isForHome) {
  532.             if (resJson.alreadySynced) {
  533.               if (!this.state.isFilter) {
  534.  
  535.                 var lastArticleTimestamp;
  536.                 var artLength = articleList.length;
  537.                 if (artLength != 0) {
  538.                   lastArticleTimestamp = articleList[artLength - 1].createdAt;
  539.                 }
  540.  
  541.                 var tempJson = {
  542.                   "limit": pagingCount,
  543.                   "offset": 0
  544.                 };
  545.                 if (artLength > pagingCount) {
  546.                   tempJson["lastTimestamp"] = lastArticleTimestamp;
  547.                 }
  548.                 this.loadSyncedSql(tempJson);
  549.               } else {
  550.                 //TO DO: filter is applied
  551.               }
  552.             } else {
  553.               var tempJson = {
  554.                 "limit": pagingCount,
  555.                 "offset": 0
  556.               };
  557.               articleList = [];
  558.               this.loadSqlArticle(tempJson);
  559.             }
  560.           }
  561.         } else {
  562.           // console.log("article observable error else");
  563.           this.setState({ refresh: !this.state.refresh, articleLoading: false, articleLength: articleList.length });
  564.         }
  565.       },
  566.         () => {
  567.           // console.log("article observable error");
  568.           this.setState({ refresh: !this.state.refresh, articleLoading: false, articleLength: articleList.length });
  569.         }
  570.       );
  571.     }
  572.   }
  573.  
  574.   processArticleList(data, articleCount) {
  575.     for (var i = 0; i < data.length; i++) {
  576.       var tagList = [];
  577.       if (data[i]["tagList"]) {
  578.         tagList = data[i]["tagList"].split("*");
  579.       }
  580.       tagList.sort(colProvider.SortByNameArray);
  581.       var currentTimestamp = new Date();
  582.       var articleTimestamp = new Date(data[i].createdAt);
  583.       var timeAgo = humanize(currentTimestamp, articleTimestamp);
  584.       var articleType = data[i].type;
  585.       var phImage = colProvider.getPlaceholderImage(articleType);
  586.       var phImageBig = articleType == "HTML" && colProvider.getPlaceholderImageBig(articleType);
  587.       var bgColor = colProvider.getArticleBg(articleType);
  588.       articleList.push({
  589.         "id": data[i].id,
  590.         "title": data[i].title,
  591.         "url": data[i].url,
  592.         "timeAgo": timeAgo.time + translate(staticConfig[timeAgo.timeUnit]),
  593.         "imageURL": data[i].imageURL,
  594.         "image": phImage,
  595.         "cardImage": phImageBig,
  596.         "collectionName": data[i].collectionName,
  597.         "collectionId": data[i].collectionId,
  598.         "collectionType": data[i].collectionType,
  599.         "type": articleType,
  600.         "hostname": colProvider.getHostname(data[i].url),
  601.         "highlightData": [],
  602.         "tagList": tagList,
  603.         "isReadable": data[i].isReadable == 1 ? true : false,
  604.         "viaTemplate": data[i].viaTemplate == 1 ? true : false,
  605.         "isImageAvailable": data[i].isImageAvailable == 1 ? true : false,
  606.         "isFavorite": data[i].isFavorite == 1 ? true : false,
  607.         "readStatus": data[i].readStatus == 1 ? true : false,
  608.         "isImageFailed": data[i].isImageFailed == 1 ? true : false,
  609.         "isDataFailed": data[i].isDataFailed == 1 ? true : false,
  610.         "createdAt": data[i].createdAt,
  611.         "updatedAt": data[i].updatedAt,
  612.         "bgColor": bgColor,
  613.         "contentURL": data[i].contentURL,
  614.         "isPushed": data[i].isPushed == 1 ? true : false,
  615.         "pushType": data[i].pushType
  616.       });
  617.  
  618.       if (articleList[articleCount].isImageAvailable && !articleList[articleCount].isImageFailed) {
  619.         this.loadArticleImage(articleList[articleCount]);
  620.       }
  621.       if (articleList[articleCount].type == "PDF") {
  622.         this.loadPDFFileStatus(articleList[articleCount]);
  623.       }
  624.  
  625.       articleCount++;
  626.     }
  627.     // console.log(articleList);
  628.     this.setState({ refresh: !this.state.refresh, articleLoading: false, footerLoading: false, articleLength: articleList.length });
  629.   }
  630.  
  631.   //to fetch the article list from sqlite
  632.   loadSyncedSql(tempJson) {
  633.     colProvider.getArticleSql(tempJson).then((data) => {
  634.       // console.log(data);
  635.  
  636.       if (data.length < pagingCount) {
  637.         noMoreData = true;
  638.       }
  639.       if (data.length != 0) {
  640.         var articleCount = 0;
  641.         var tp = [];
  642.         var artLength = articleList.length;
  643.         var firstArticleTimestamp;
  644.         var urlMD, shortPath;
  645.  
  646.         var loadedPDFId = [], loadedPDFStatus = [];
  647.         for (var k = 0; k < articleList.length; k++) {
  648.           if (articleList[k].isPDFAvailable) {
  649.             loadedPDFId.push(articleList[k].id);
  650.             loadedPDFStatus.push(articleList[k].isPDFAvailable);
  651.           }
  652.         }
  653.  
  654.         if (artLength != 0) {
  655.           firstArticleTimestamp = articleList[0].createdAt;
  656.         }
  657.         var currentArticleTimestamp, isImagePath;
  658.         for (var i = 0; i < data.length; i++) {
  659.           var tagList = [];
  660.           if (data[i]["tagList"]) {
  661.             tagList = data[i]["tagList"].split("*");
  662.           }
  663.           tagList.sort(colProvider.SortByNameArray);
  664.           var currentTimestamp = new Date();
  665.           var articleTimestamp = new Date(data[i].createdAt);
  666.           var timeAgo = humanize(currentTimestamp, articleTimestamp);
  667.           currentArticleTimestamp = data[i].createdAt;
  668.           isImagePath = false;
  669.           urlMD = MD5.MD5(data[i].url);
  670.           shortPath = RNFetchBlob.fs.dirs.DocumentDir + "/" + urlMD + ".jpg";
  671.           if (currentArticleTimestamp <= firstArticleTimestamp) {
  672.             isImagePath = true;
  673.           }
  674.  
  675.           var articleType = data[i].type;
  676.  
  677.           var isPDFAvailable = null;
  678.           if (articleType == "PDF") {
  679.             if (loadedPDFId.length != 0) {
  680.               var pdfIndex = loadedPDFId.indexOf(data[i].id);
  681.               if (pdfIndex != -1) {
  682.                 isPDFAvailable = loadedPDFStatus[pdfIndex];
  683.               }
  684.             }
  685.           }
  686.  
  687.           var phImage;
  688.           if (isImagePath && data[i].isImageAvailable == 1 && data[i].isImageFailed != 1) {
  689.             phImage = "file://" + shortPath;
  690.           } else {
  691.             phImage = (isPDFAvailable == "false") ? colProvider.getPdfNAImage() : colProvider.getPlaceholderImage(articleType);
  692.           }
  693.           var phImageBig = articleType == "HTML" && colProvider.getPlaceholderImageBig(articleType);
  694.           var bgColor = (isPDFAvailable == "false") ? colProvider.getPdfNABg() : colProvider.getArticleBg(articleType);
  695.           tp.push({
  696.             "id": data[i].id,
  697.             "title": data[i].title,
  698.             "url": data[i].url,
  699.             "timeAgo": timeAgo.time + translate(staticConfig[timeAgo.timeUnit]),
  700.             "imageURL": data[i].imageURL,
  701.             "image": phImage,
  702.             "cardImage": phImageBig,
  703.             "collectionName": data[i].collectionName,
  704.             "collectionId": data[i].collectionId,
  705.             "collectionType": data[i].collectionType,
  706.             "type": articleType,
  707.             "hostname": colProvider.getHostname(data[i].url),
  708.             "highlightData": [],
  709.             "tagList": tagList,
  710.             "isReadable": data[i].isReadable == 1 ? true : false,
  711.             "viaTemplate": data[i].viaTemplate == 1 ? true : false,
  712.             "isImageAvailable": data[i].isImageAvailable == 1 ? true : false,
  713.             "isFavorite": data[i].isFavorite == 1 ? true : false,
  714.             "readStatus": data[i].readStatus == 1 ? true : false,
  715.             "isImageFailed": data[i].isImageFailed == 1 ? true : false,
  716.             "isDataFailed": data[i].isDataFailed == 1 ? true : false,
  717.             "isPDFAvailable": isPDFAvailable,
  718.             "createdAt": data[i].createdAt,
  719.             "updatedAt": data[i].updatedAt,
  720.             "bgColor": bgColor,
  721.             "contentURL": data[i].contentURL,
  722.             "isPushed": data[i].isPushed == 1 ? true : false,
  723.             "pushType": data[i].pushType
  724.           });
  725.           if (!isImagePath && tp[articleCount].isImageAvailable && !tp[articleCount].isImageFailed) {
  726.             this.loadArticleImage(tp[articleCount]);
  727.           }
  728.           if (tp[articleCount].type == "PDF" && !isPDFAvailable) {
  729.             this.loadPDFFileStatus(tp[articleCount]);
  730.           }
  731.  
  732.           articleCount++;
  733.         }
  734.         articleList = tp;
  735.         // console.log(articleList);
  736.         this.setState({ refresh: !this.state.refresh, articleLoading: false, footerLoading: false, articleLength: articleList.length });
  737.       } else {
  738.         articleList = [];
  739.         this.setState({ refresh: !this.state.refresh, articleLoading: false, footerLoading: false, articleLength: articleList.length });
  740.       }
  741.     });
  742.   }
  743.  
  744.   async loadPDFFileStatus(articleItem) {
  745.     var isExist = await colProvider.checkIfPDFFileAvailable(articleItem);
  746.     var isExistStr = isExist.toString();
  747.     articleItem.isPDFAvailable = isExistStr;
  748.     if (articleItem.isPDFAvailable == "false") {
  749.       articleItem.bgColor = colProvider.getPdfNABg();
  750.       articleItem.image = colProvider.getPdfNAImage();
  751.     }
  752.     this.setState({
  753.       refresh: !this.state.refresh
  754.     });
  755.   }
  756.  
  757.   //load the article image from file storage
  758.   loadArticleImage(articleItem, failureCount) {
  759.     var urlMD = MD5.MD5(articleItem.url);
  760.     var path = RNFetchBlob.fs.dirs.DocumentDir + "/" + urlMD + ".jpg";
  761.     RNFetchBlob.fs.exists(path).then((exist) => {
  762.       if (exist) {
  763.         for (var i = 0; i < articleList.length; i++) {
  764.           if (articleList[i].id == articleItem.id) {
  765.             articleList[i].image = "file://" + path;
  766.             break;
  767.           }
  768.         }
  769.         this.setState({ refresh: !this.state.refresh });
  770.       }
  771.       else {
  772.         AsyncStorage.getItem("accountId").then((accountId) => {
  773.           var path = accountId + "/" + urlMD + "/" + urlMD + ".jpg";
  774.           if (articleItem.isPushed) {
  775.             if (!failureCount) {
  776.               failureCount = 3;
  777.             }
  778.             this.writeArticleImage(articleItem.imageURL, urlMD, articleItem, failureCount);
  779.           }
  780.           else {
  781.             colProvider.getArticleImageGraph(path).then((data) => {
  782.               if (!failureCount) {
  783.                 failureCount = 3;
  784.               }
  785.               this.writeArticleImage(data, urlMD, articleItem, failureCount);
  786.             });
  787.           }
  788.         });
  789.       }
  790.     });
  791.   }
  792.  
  793.   //download the article image to file storage
  794.   writeArticleImage(data, urlMD, articleItem, failureCount) {
  795.     var path = RNFetchBlob.fs.dirs.DocumentDir + "/" + urlMD + ".jpg";
  796.     RNFetchBlob
  797.       .config({
  798.         fileCache: true,
  799.         path: path
  800.       })
  801.       .fetch('GET', data, {
  802.       })
  803.       .then((res) => {
  804.         if (res["respInfo"] && res["respInfo"]["headers"]) {
  805.           var types = colProvider.findValueOfProperty(res["respInfo"]["headers"], "content-type");
  806.           if (types.length != 0) {
  807.             var ctype = types[0];
  808.             if (res["respInfo"]["status"] == 200) {
  809.               if (ctype.indexOf("xml") == -1 && ctype.indexOf("html") == -1) {
  810.                 // content type is neither 'xml' nor 'html', so save and set the image
  811.                 var aPath = "file://" + res.path();
  812.                 for (var i = 0; i < articleList.length; i++) {
  813.                   if (articleList[i].id == articleItem.id) {
  814.                     articleList[i].image = aPath;
  815.                     break;
  816.                   }
  817.                 }
  818.                 this.setState({ refresh: !this.state.refresh });
  819.               } else {
  820.                 // content type is either 'xml' or 'html', so set imageFailed to true and remove the image file
  821.                 this.updateImageFailedArticle(articleItem, res.path(), failureCount);
  822.               }
  823.             } else if (res["respInfo"]["status"] == 404) {
  824.               // image file not found on server
  825.               this.updateImageFailedArticle(articleItem, res.path(), failureCount);
  826.             } else {
  827.               // some other status code, so remove the image file(it will be retried on next app launch or sync)
  828.               RNFetchBlob.fs.unlink(res.path());
  829.             }
  830.           } else {
  831.             //content type is application/xml
  832.             this.updateImageFailedArticle(articleItem, res.path(), failureCount);
  833.           }
  834.         }
  835.       })
  836.   }
  837.  
  838.   updateImageFailedArticle(articleItem, filePath, failureCount) {
  839.     if (failureCount <= 1) {
  840.       var queryArg = "isImageFailed = 1";
  841.       var queryData = [articleItem.id];
  842.       colProvider.updateSingleArticleSql(queryArg, queryData);
  843.  
  844.       RNFetchBlob.fs.unlink(filePath);
  845.     } else {
  846.       failureCount--;
  847.       RNFetchBlob.fs.unlink(filePath);
  848.       setTimeout(() => {
  849.         this.loadArticleImage(articleItem, failureCount);
  850.       }, 3000);
  851.     }
  852.   }
  853.  
  854.   openSearch() {
  855.     const { navigate } = this.props.navigation;
  856.     navigate('Search', { screenName: "Collection" });
  857.   }
  858.  
  859.   openMenu() {
  860.     this.drawer.openDrawer();
  861.   }
  862.  
  863.   //initialize all required values when switched between portrait and landscape
  864.   initMaxHeight() {
  865.     var sheight = Dimensions.get('window').height;
  866.     var swidth = Dimensions.get('window').width;
  867.     screenWidth = swidth;
  868.     if (sheight < 480) {
  869.       this.setState({ isMaxHeight: true });
  870.     }
  871.     else {
  872.       this.setState({ isMaxHeight: false });
  873.     }
  874.  
  875.     if (sheight < 480) {
  876.       modalHeight = 250;
  877.     }
  878.     else {
  879.       modalHeight = null;
  880.     }
  881.  
  882.     if (swidth < 480) {
  883.       numberOfCards = 1;
  884.       cardWidth = swidth - 32;
  885.       modalWidth = "100%";
  886.     }
  887.     else if (swidth < 920) {
  888.       numberOfCards = 2;
  889.       cardWidth = (swidth / 2) - 24;
  890.       modalWidth = "70%";
  891.     }
  892.     else {
  893.       numberOfCards = 3;
  894.       cardWidth = (swidth / 3) - 22;
  895.       modalWidth = "60%";
  896.     }
  897.     var tempCardWidth = cardWidth - moderateScale(94, 0.2);
  898.     cardLeftWidth = tempCardWidth;
  899.     this.setState({ refresh: !this.state.refresh });
  900.   }
  901.  
  902.   //to switch between listview and cardview
  903.   changeView() {
  904.     var viewState = !this.state.isCardView;
  905.     this.setState({ isCardView: viewState });
  906.     AsyncStorage.setItem("isCardView", viewState.toString());
  907.     // apiProvider.refreshToken();
  908.   }
  909.  
  910.   //start local subscription of articles for remote subscription
  911.   startArticleSubscription() {
  912.     // colProvider.startArticleSubscriptionGraph().subscribe((resJson) => {
  913.     varProvider.artSubObserver.subscribe((resJson) => {
  914.       // console.log("article subscription");
  915.       // console.log(resJson);
  916.       if (!resJson.error) {
  917.         var data = resJson.data;
  918.         var subObject = data["data"]["articleSubscribe"];
  919.         var articleNode = data["data"]["articleSubscribe"]["node"];
  920.         var prevArticleNode = data["data"]["articleSubscribe"]["previousValues"];
  921.         /*if (subObject.mutation == "UPDATED") {
  922.           var updatedFields = subObject["updatedFields"];
  923.           if (updatedFields && updatedFields.length != 0) {
  924.             for (var i = 0; i < articleList.length; i++) {
  925.               if (articleList[i].id == articleNode.id) {
  926.                 for (var j = 0; j < updatedFields.length; j++) {
  927.                   articleList[i][updatedFields[j]] = articleNode[updatedFields[j]];
  928.                 }
  929.               }
  930.             }
  931.           } else {
  932.             //collection and tags case
  933.             var tagLength = articleNode["tags"].length;
  934.             var inCollection = false;
  935.             for (var i = 0; i < articleList.length; i++) {
  936.               if (articleList[i].id == articleNode.id) {
  937.                 inCollection = true;
  938.                 //delete article if moved from collection
  939.                 if (articleList[i].collectionId != articleNode["collection"][0]["id"]) {
  940.                   articleList.splice(i, 1);
  941.                   break;
  942.                 }
  943.  
  944.                 //update taglist of article
  945.                 var tagList = [];
  946.                 if (tagLength != 0) {
  947.                   var arrTag = articleNode["tags"];
  948.                   for (var m = 0; m < arrTag.length; m++) {
  949.                     tagList.push(arrTag[m].name);
  950.                   }
  951.                   articleList[i]["tagList"] = tagList;
  952.                 } else {
  953.                   articleList[i]["tagList"] = [];
  954.                 }
  955.               }
  956.             }
  957.  
  958.             //article not in current collection so insert article
  959.             if (!inCollection) {
  960.               //check if articles collection id has changed and updated to current collectionid
  961.               var tempJson = {
  962.                 "id": articleNode.id
  963.               };
  964.               colProvider.getSingleArticleSql(tempJson).then((articleItem) => {
  965.                 // console.log(articleItem);
  966.                 if (articleItem[0].collectionId != articleNode["collection"][0]["id"]) {
  967.                   if (articleNode["collection"][0]["id"] == varProvider.selectedCollectionId) {
  968.                     var tagList = [];
  969.                     if (articleItem[0]["tagList"]) {
  970.                       tagList = articleItem[0]["tagList"].split("*");
  971.                     }
  972.                     var currentTimestamp = new Date();
  973.                     var articleTimestamp = new Date(articleItem[0].createdAt);
  974.                     var timeAgo = humanize(currentTimestamp, articleTimestamp);
  975.                     articleList.unshift({
  976.                       "id": articleItem[0].id,
  977.                       "title": articleItem[0].title,
  978.                       "url": articleItem[0].url,
  979.                       "timeAgo": timeAgo,
  980.                       "imageURL": articleItem[0].imageURL,
  981.                       "collectionName": articleItem[0].collectionName,
  982.                       "collectionId": articleItem[0].collectionId,
  983.                       "type": articleItem[0].type,
  984.                       "hostname": colProvider.getHostname(articleItem[0].url),
  985.                       "highlightData": [],
  986.                       "tagList": tagList,
  987.                       "isReadable": articleItem[0].isReadable == 1 ? true : false,
  988.                       "isImageAvailable": articleItem[0].isImageAvailable == 1 ? true : false,
  989.                       "isFavorite": articleItem[0].isFavorite == 1 ? true : false,
  990.                       "readStatus": articleItem[0].readStatus == 1 ? true : false,
  991.                       "createdAt": articleItem[0].createdAt,
  992.                       "updatedAt": articleItem[0].updatedAt
  993.                     });
  994.  
  995.                     if (articleList[0].isImageAvailable) {
  996.                       this.loadArticleImage(articleList[0]);
  997.                     }
  998.                   }
  999.                 }
  1000.               });
  1001.             }
  1002.  
  1003.           }
  1004.         }*/
  1005.         if (subObject.mutation == "CREATED") {
  1006.  
  1007.           var alreadyAdded = false;
  1008.           for (var i = 0; i < articleList.length; i++) {
  1009.             if (articleList[i].url == articleNode.url) {
  1010.               alreadyAdded = true;
  1011.               break;
  1012.             }
  1013.           }
  1014.           // console.log("subscription already added: " + alreadyAdded);
  1015.  
  1016.           if (!alreadyAdded) {
  1017.             var tagList = [];
  1018.             if (articleNode["tags"].length != 0) {
  1019.               var arrTag = articleNode["tags"];
  1020.               for (var m = 0; m < arrTag.length; m++) {
  1021.                 tagList.push(arrTag[m].name);
  1022.               }
  1023.             }
  1024.             tagList.sort(colProvider.SortByNameArray);
  1025.             var collectionName = "", collectionId = "", collectionType = "";
  1026.             if (articleNode["collection"].length != 0) {
  1027.               collectionId = articleNode["collection"][0]["id"];
  1028.               collectionName = articleNode["collection"][0]["title"];
  1029.               collectionType = articleNode["collection"][0]["type"];
  1030.             }
  1031.  
  1032.             if (varProvider.selectedCollectionId == collectionId) {
  1033.  
  1034.               var currentTimestamp = new Date();
  1035.               var articleTimestamp = new Date(articleNode.createdAt);
  1036.               var timeAgo = humanize(currentTimestamp, articleTimestamp);
  1037.               var articleType = articleNode.isPushed ? articleNode.refArticle.type : articleNode.type;
  1038.               var phImage = colProvider.getPlaceholderImage(articleType);
  1039.               var phImageBig = articleType == "HTML" && colProvider.getPlaceholderImageBig(articleType);
  1040.               var bgColor = colProvider.getArticleBg(articleType);
  1041.               articleList.unshift({
  1042.                 "id": articleNode.id,
  1043.                 "title": articleNode.isPushed ? articleNode.refArticle.title : articleNode.title,
  1044.                 "url": articleNode.isPushed ? articleNode.refArticle.url : articleNode.url,
  1045.                 "timeAgo": timeAgo.time + translate(staticConfig[timeAgo.timeUnit]),
  1046.                 "imageURL": articleNode.isPushed ? articleNode.refArticle.imageURL : articleNode.imageURL,
  1047.                 "image": phImage,
  1048.                 "cardImage": phImageBig,
  1049.                 "collectionName": collectionName,
  1050.                 "collectionId": collectionId,
  1051.                 "collectionType": collectionType,
  1052.                 "type": articleType,
  1053.                 "hostname": colProvider.getHostname(articleNode.url),
  1054.                 "highlightData": [],
  1055.                 "tagList": tagList,
  1056.                 "isReadable": articleNode.isPushed ? articleNode.refArticle.isScraped : articleNode.isReadable,
  1057.                 "viaTemplate": articleNode.viaTemplate,
  1058.                 "isImageAvailable": articleNode.isPushed ? articleNode.refArticle.isImageAvailable : articleNode.isImageAvailable,
  1059.                 "isFavorite": articleNode.isFavorite,
  1060.                 "readStatus": articleNode.readStatus,
  1061.                 "isImageFailed": false,
  1062.                 "isDataFailed": false,
  1063.                 "createdAt": new Date(articleNode.createdAt).getTime(),
  1064.                 "updatedAt": new Date(articleNode.updatedAt).getTime(),
  1065.                 "bgColor": bgColor,
  1066.                 "contentURL": articleNode.isPushed ? articleNode.refArticle.contentURL : articleNode.contentURL,
  1067.                 "isPushed": articleNode.isPushed,
  1068.                 "pushType": articleNode.isPushed ? articleNode.refArticle.pushType : ""
  1069.               });
  1070.  
  1071.               if (articleList[0].isImageAvailable) {
  1072.                 this.loadArticleImage(articleList[0]);
  1073.               }
  1074.               if (articleList[0].type == "PDF") {
  1075.                 this.loadPDFFileStatus(articleList[0]);
  1076.               }
  1077.  
  1078.             }
  1079.           }
  1080.  
  1081.         } else if (subObject.mutation == "DELETED") {
  1082.           for (var i = 0; i < articleList.length; i++) {
  1083.             if (articleList[i].id == prevArticleNode.id) {
  1084.               articleList.splice(i, 1);
  1085.               if (articleList.length < pagingCount && !noMoreData) {
  1086.                 setTimeout(() => {
  1087.                   this.handleLoadMore({ distanceFromEnd: "NeedToFetch" });
  1088.                 }, 1000);
  1089.               }
  1090.               break;
  1091.             }
  1092.           }
  1093.         }
  1094.  
  1095.         this.setState({ refresh: !this.state.refresh });
  1096.       }
  1097.     });
  1098.   }
  1099.  
  1100.   //start local subscription of collections for remote subscription
  1101.   startCollectionSubscription() {
  1102.     // colProvider.startCollectionSubscriptionGraph().subscribe((resJson) => {
  1103.     varProvider.colSubObserver.subscribe((resJson) => {
  1104.       // console.log("collection subscription");
  1105.       // console.log(resJson);
  1106.       if (!resJson.error) {
  1107.         var data = resJson.data;
  1108.         var subObject = data["data"]["collectionsSubscribe"];
  1109.         var collectionNode = data["data"]["collectionsSubscribe"]["node"];
  1110.         var prevCollectionNode = data["data"]["collectionsSubscribe"]["previousValues"];
  1111.         /*if (subObject.mutation == "UPDATED") {
  1112.  
  1113.           var updatedFields = subObject["updatedFields"];
  1114.           if (updatedFields && updatedFields.length != 0) {
  1115.             for (var i = 0; i < collectionList.length; i++) {
  1116.               if (collectionList[i].id == collectionNode.id) {
  1117.                 for (var j = 0; j < updatedFields.length; j++) {
  1118.                   //update collection item according to updated field
  1119.                   collectionList[i][updatedFields[j]] = collectionNode[updatedFields[j]];
  1120.  
  1121.                   //if collection title has changed, update in article list
  1122.                   //if same collection is selected, update that title also
  1123.                   if (updatedFields[j] == "title") {
  1124.                     if (varProvider.selectedCollectionName == prevCollectionNode["title"]) {
  1125.                       varProvider.selectedCollectionName = collectionNode["title"];
  1126.                       for (var m = 0; m < articleList.length; m++) {
  1127.                         if (articleList[m].collectionName == prevCollectionNode["title"]) {
  1128.                           articleList[m].collectionName = collectionNode["title"];
  1129.                         }
  1130.                       }
  1131.                     }
  1132.                   }
  1133.                   //if collection's isDefault has changed, update default collection id and default collection
  1134.                   //title in asyncstorage and global variable
  1135.                   //set all other collection's isDefault to false
  1136.                   else if (updatedFields[j] == "isDefault") {
  1137.                     varProvider.defaultCollectionId = collectionNode.id;
  1138.                     varProvider.defaultCollectionName = collectionNode.title;
  1139.                     AsyncStorage.setItem("defaultCollectionId", varProvider.defaultCollectionId);
  1140.                     AsyncStorage.setItem("defaultCollectionName", varProvider.defaultCollectionName);
  1141.  
  1142.                     for (var t = 0; t < collectionList.length; t++) {
  1143.                       if (collectionList[t].id != collectionNode.id) {
  1144.                         collectionList[t].isDefault = false;
  1145.                       }
  1146.                     }
  1147.                   }
  1148.  
  1149.                 }
  1150.               }
  1151.             }
  1152.           }
  1153.  
  1154.         }*/
  1155.         if (subObject.mutation == "CREATED") {
  1156.  
  1157.           var alreadyAdded = false;
  1158.           for (var i = 0; i < collectionList.length; i++) {
  1159.             if (collectionList[i].title == collectionNode.title) {
  1160.               alreadyAdded = true;
  1161.               break;
  1162.             }
  1163.           }
  1164.           if (!alreadyAdded) {
  1165.             var tempColList = JSON.parse(JSON.stringify(collectionList));
  1166.             tempColList.splice(0, 1);
  1167.             var toInsertIndex = colProvider.getSortedIndex(tempColList, collectionNode.title, "title");
  1168.             collectionList.splice(toInsertIndex + 1, 0, {
  1169.               "id": collectionNode.id,
  1170.               "title": collectionNode.title,
  1171.               "description": collectionNode.description,
  1172.               "isDefault": collectionNode.isDefault,
  1173.               "createdAt": collectionNode.createdAt,
  1174.               "updatedAt": collectionNode.updatedAt,
  1175.               "pressed": false,
  1176.               "active": false
  1177.             });
  1178.           }
  1179.  
  1180.         } else if (subObject.mutation == "DELETED") {
  1181.  
  1182.           var index, colIdToDelete;
  1183.           for (var i = 0; i < collectionList.length; i++) {
  1184.             if (collectionList[i].id == prevCollectionNode.id) {
  1185.               colIdToDelete = collectionList[i].id;
  1186.               collectionList.splice(i, 1);
  1187.               index = i;
  1188.               break;
  1189.             }
  1190.           }
  1191.  
  1192.           if (varProvider.selectedCollectionId == colIdToDelete) {
  1193.             if (index) {
  1194.               if (index == 0) {
  1195.                 //select collection and load its article
  1196.                 this.selectColAndLoadArticle(index);
  1197.               } else {
  1198.                 //select collection i-1 and load its articles
  1199.                 this.selectColAndLoadArticle(index - 1);
  1200.               }
  1201.             }
  1202.           }
  1203.         }
  1204.  
  1205.         this.setState({ refreshCollection: !this.state.refreshCollection, refresh: !this.state.refresh });
  1206.       }
  1207.     });
  1208.   }
  1209.  
  1210.   buttonCallback() {
  1211.     this.callbackFun(this.state.activeFilters);
  1212.   }
  1213.  
  1214.   //if filter is applied
  1215.   callbackFun(activeFilters) {
  1216.     // console.log(activeFilters);
  1217.     graphError = "";
  1218.     this.setState({ activeFilters: activeFilters, articleLoading: true, errorLoading: false, articleLength: 0 });
  1219.  
  1220.     var isFilter = false;
  1221.     var appliedFilter = [];
  1222.     for (var i = 0; i < activeFilters.length; i++) {
  1223.       if (activeFilters[i].active) {
  1224.         isFilter = true;
  1225.         var topKey, bottomKey, dataKey, dataValue, sqlKey, sqlValue;
  1226.         //filter by days
  1227.         if (i == 0) {
  1228.           let minimumDate = activeFilters[0].value[0];
  1229.           let maximumDate = activeFilters[0].value[1];
  1230.  
  1231.           topKey = "$createdAt_gte: DateTime, $createdAt_lte: DateTime";
  1232.           bottomKey = "createdAt_gte: $createdAt_gte, createdAt_lte: $createdAt_lte";
  1233.           dataKey = "dateRange";
  1234.           dataValue = [minimumDate, maximumDate];
  1235.           sqlKey = "al.createdAt >= ? AND al.createdAt <= ?";
  1236.           sqlValue = [new Date(minimumDate).getTime(), new Date(maximumDate).getTime()];
  1237.         }
  1238.         //filter favorite
  1239.         if (i == 3) {
  1240.           topKey = "$isFavorite: Boolean";
  1241.           bottomKey = "isFavorite: $isFavorite";
  1242.           dataKey = "isFavorite";
  1243.           dataValue = true;
  1244.           sqlKey = "al.isFavorite = ?";
  1245.           sqlValue = 1;
  1246.         }
  1247.         //filter by tag
  1248.         if (i == 4) {
  1249.           topKey = "$tagName: [String!]";
  1250.           bottomKey = "tags_some: { name_in: $tagName }";
  1251.           dataKey = "tagName";
  1252.           dataValue = activeFilters[4].value;
  1253.           sqlKey = "tl.title = ?";
  1254.           sqlValue = activeFilters[4].value;
  1255.         }
  1256.         //filter by search text
  1257.         if (i == 5) {
  1258.           topKey = "$searchText: String";
  1259.           bottomKey = "title_contains: $searchText ";
  1260.           dataKey = "searchText";
  1261.           dataValue = activeFilters[5].value;
  1262.           sqlKey = "al.title LIKE ?";
  1263.           sqlValue = "%" + activeFilters[5].value + "%";
  1264.         }
  1265.         if (i == 1 || i == 2) {
  1266.         } else {
  1267.           appliedFilter.push({
  1268.             "topKey": topKey,
  1269.             "bottomKey": bottomKey,
  1270.             "dataKey": dataKey,
  1271.             "dataValue": dataValue,
  1272.             "sqlKey": sqlKey,
  1273.             "sqlValue": sqlValue
  1274.           });
  1275.         }
  1276.       }
  1277.     }
  1278.  
  1279.     var typeFilter;
  1280.     if (activeFilters[1].active) {
  1281.       typeFilter = "HTML";
  1282.     }
  1283.  
  1284.     if (activeFilters[2].active) {
  1285.       typeFilter = "PDF";
  1286.     }
  1287.  
  1288.     if (activeFilters[1].active && activeFilters[2].active) {
  1289.       typeFilter = "";
  1290.     }
  1291.  
  1292.     if (!activeFilters[1].active && !activeFilters[2].active) {
  1293.       typeFilter = "";
  1294.     }
  1295.  
  1296.     if (typeFilter) {
  1297.       appliedFilter.push({
  1298.         "topKey": "$type: ArticleType",
  1299.         "bottomKey": "type: $type",
  1300.         "dataKey": "type",
  1301.         "dataValue": typeFilter,
  1302.         "sqlKey": "al.type = ?",
  1303.         "sqlValue": typeFilter
  1304.       });
  1305.     }
  1306.  
  1307.     if (appliedFilter.length == 0) {
  1308.       this.setState({
  1309.         "isFilter": false,
  1310.         appliedFilter: appliedFilter
  1311.       });
  1312.     } else {
  1313.       this.setState({
  1314.         "isFilter": true,
  1315.         appliedFilter: appliedFilter
  1316.       });
  1317.     }
  1318.  
  1319.     //load favorite articles if favorite articles is selected
  1320.     //and add search filter if already applied
  1321.     if (varProvider.selectedCollectionId == "favoriteArticles") {
  1322.       var filLength = appliedFilter.length;
  1323.       var searchText = (filLength == 0) ? "" : appliedFilter[0].sqlValue;
  1324.       var tempJson = {
  1325.         "isFilter": (filLength != 0),
  1326.         "offset": 0,
  1327.         "searchText": searchText
  1328.       };
  1329.  
  1330.       articleList = [];
  1331.       noMoreData = false;
  1332.       //sql query to filter favorite article list      
  1333.       this.loadFavoriteArticles(tempJson);
  1334.     } else {
  1335.       //if internet is connected load article list from api
  1336.       //else load article list from sqlite
  1337.       if (connection.isConnectedFun()) {
  1338.         if (appliedFilter.length != 0) {
  1339.           var tempJson = {
  1340.             "isFilter": isFilter,
  1341.             "appliedFilter": appliedFilter,
  1342.             "first": pagingCount,
  1343.             "skip": 0
  1344.           };
  1345.  
  1346.           articleList = [];
  1347.           noMoreData = false;
  1348.           //graphql query to filter article list
  1349.           this.loadGraphArticle(tempJson);
  1350.  
  1351.         } else {
  1352.           isFirstTime = false;
  1353.           this.loadArticleList();
  1354.         }
  1355.       } else {
  1356.         if (appliedFilter.length != 0) {
  1357.           var tempJson = {
  1358.             "isFilter": isFilter,
  1359.             "appliedFilter": appliedFilter,
  1360.             "limit": pagingCount,
  1361.             "offset": 0
  1362.           };
  1363.  
  1364.           articleList = [];
  1365.           noMoreData = false;
  1366.           //sql query to filter article list      
  1367.           this.loadSqlArticle(tempJson);
  1368.         }
  1369.         else {
  1370.           isFirstTime = false;
  1371.           this.loadArticleList();
  1372.         }
  1373.       }
  1374.     }
  1375.   }
  1376.  
  1377.   //load article list from api
  1378.   loadGraphArticle(tempJson) {
  1379.     colProvider.getArticleListGraph(tempJson).then((data) => {
  1380.       // console.log("load graph article data");
  1381.       // console.log(data);
  1382.  
  1383.       if (data.length < pagingCount) {
  1384.         noMoreData = true;
  1385.       }
  1386.       if (data.length != 0) {
  1387.         var articleCount = articleList.length;
  1388.         for (var i = 0; i < data.length; i++) {
  1389.           var tagList = [];
  1390.           if (data[i]["tags"].length != 0) {
  1391.             var arrTag = data[i]["tags"];
  1392.             for (var m = 0; m < arrTag.length; m++) {
  1393.               tagList.push(arrTag[m].name);
  1394.             }
  1395.           }
  1396.           tagList.sort(colProvider.SortByNameArray);
  1397.           var collectionName = "", collectionId = "", collectionType = "";
  1398.           if (data[i]["collection"].length != 0) {
  1399.             collectionId = data[i]["collection"][0]["id"];
  1400.             collectionName = data[i]["collection"][0]["title"];
  1401.             collectionType = data[i]["collection"][0]["type"];
  1402.           }
  1403.           var currentTimestamp = new Date();
  1404.           var articleTimestamp = new Date(data[i].createdAt);
  1405.           var timeAgo = humanize(currentTimestamp, articleTimestamp);
  1406.           var articleType = data[i].isPushed ? data[i].refArticle.type : data[i].type;
  1407.           var phImage = colProvider.getPlaceholderImage(articleType);
  1408.           var phImageBig = articleType == "HTML" && colProvider.getPlaceholderImageBig(articleType);
  1409.           var bgColor = colProvider.getArticleBg(articleType);
  1410.           articleList.push({
  1411.             "id": data[i].id,
  1412.             "title": data[i].isPushed ? data[i].refArticle.title : data[i].title,
  1413.             "url": data[i].isPushed ? data[i].refArticle.url : data[i].url,
  1414.             "timeAgo": timeAgo.time + translate(staticConfig[timeAgo.timeUnit]),
  1415.             "imageURL": data[i].isPushed ? data[i].refArticle.imageURL : data[i].imageURL,
  1416.             "image": phImage,
  1417.             "cardImage": phImageBig,
  1418.             "collectionName": collectionName,
  1419.             "collectionId": collectionId,
  1420.             "collectionType": collectionType,
  1421.             "type": articleType,
  1422.             "hostname": colProvider.getHostname(data[i].url),
  1423.             "highlightData": [],
  1424.             "tagList": tagList,
  1425.             "isReadable": data[i].isPushed ? data[i].refArticle.isScraped : data[i].isReadable,
  1426.             "viaTemplate": data[i].viaTemplate,
  1427.             "isImageAvailable": data[i].isPushed ? data[i].refArticle.isImageAvailable : data[i].isImageAvailable,
  1428.             "isFavorite": data[i].isFavorite,
  1429.             "readStatus": data[i].readStatus,
  1430.             "isImageFailed": false,
  1431.             "isDataFailed": false,
  1432.             "createdAt": new Date(data[i].createdAt).getTime(),
  1433.             "updatedAt": new Date(data[i].updatedAt).getTime(),
  1434.             "bgColor": bgColor,
  1435.             "contentURL": data[i].isPushed ? data[i].refArticle.contentURL : data[i].contentURL,
  1436.             "isPushed": data[i].isPushed,
  1437.             "pushType": data[i].isPushed ? data[i].refArticle.pushType : ""
  1438.  
  1439.           });
  1440.  
  1441.           if (articleList[articleCount].isImageAvailable && !articleList[articleCount].isImageFailed) {
  1442.             this.loadArticleImage(articleList[articleCount]);
  1443.           }
  1444.  
  1445.           if (articleList[articleCount].type == "PDF") {
  1446.             this.loadPDFFileStatus(articleList[articleCount]);
  1447.           }
  1448.  
  1449.           articleCount++;
  1450.         }
  1451.         this.setState({ refresh: !this.state.refresh, articleLoading: false, footerLoading: false, articleLength: articleList.length });
  1452.       } else {
  1453.         this.setState({ refresh: !this.state.refresh, articleLoading: false, footerLoading: false, articleLength: articleList.length });
  1454.       }
  1455.       setTimeout(() => {
  1456.         isInfiniteOn = false;
  1457.       }, 400);
  1458.     }).catch((error) => {
  1459.       // console.log(error);
  1460.       connection.getGraphError(error.error).then((data) => {
  1461.         graphError = data;
  1462.         this.setState({ refresh: !this.state.refresh, articleLoading: false, footerLoading: false, errorLoading: true, articleLength: articleList.length });
  1463.  
  1464.       })
  1465.  
  1466.       isInfiniteOn = false;
  1467.     });
  1468.   }
  1469.  
  1470.   //load article list from sqlite
  1471.   loadSqlArticle(tempJson) {
  1472.     colProvider.getArticleSql(tempJson).then((data) => {
  1473.       // console.log(data);
  1474.  
  1475.       if (data.length < pagingCount) {
  1476.         noMoreData = true;
  1477.       }
  1478.       if (data.length != 0) {
  1479.         var articleCount = articleList.length;
  1480.         this.processArticleList(data, articleCount);
  1481.       } else {
  1482.         this.setState({ refresh: !this.state.refresh, articleLoading: false, footerLoading: false, articleLength: articleList.length });
  1483.       }
  1484.       isInfiniteOn = false;
  1485.     });
  1486.   }
  1487.  
  1488.   openFilters() {
  1489.     const { navigate } = this.props.navigation;
  1490.     navigate('ColFilters', { "callbackFun": this.callbackFun, "activeFilters": this.state.activeFilters });
  1491.   }
  1492.  
  1493.   // to handle scroll pagination to load more articles
  1494.   handleLoadMore = (calledFrom) => {
  1495.     if (articleList.length > pagingCount - 1 || calledFrom.distanceFromEnd == "NeedToFetch") {
  1496.       var tempOffset = articleList.length;
  1497.  
  1498.       if (!noMoreData) {
  1499.         if (!isInfiniteOn) {
  1500.           this.setState({ footerLoading: true });
  1501.           isInfiniteOn = true;
  1502.           //load favorite articles if favorite articles is selected
  1503.           //and add search filter if already applied
  1504.           if (varProvider.selectedCollectionId == "favoriteArticles") {
  1505.             if (this.state.isFilter) {
  1506.               var filLength = this.state.appliedFilter.length;
  1507.               var searchText = (filLength == 0) ? "" : this.state.appliedFilter[0].sqlValue;
  1508.               var tempJson = {
  1509.                 "isFilter": (filLength != 0),
  1510.                 "offset": tempOffset,
  1511.                 "searchText": searchText
  1512.               };
  1513.             } else {
  1514.               var tempJson = {
  1515.                 "offset": tempOffset
  1516.               };
  1517.             }
  1518.             this.loadFavoriteArticles(tempJson);
  1519.           } else {
  1520.             if (this.state.isFilter && connection.isConnectedFun()) {
  1521.               //filter is applied
  1522.               var tempSkip = articleList.length;
  1523.  
  1524.               var tempJson = {
  1525.                 "isFilter": this.state.isFilter,
  1526.                 "appliedFilter": this.state.appliedFilter,
  1527.                 "first": pagingCount,
  1528.                 "skip": tempSkip
  1529.               };
  1530.               this.loadGraphArticle(tempJson);
  1531.             } else {
  1532.               //no filter
  1533.               var tempOffset = articleList.length;
  1534.  
  1535.               var tempJson = {
  1536.                 "isFilter": this.state.isFilter,
  1537.                 "appliedFilter": this.state.appliedFilter,
  1538.                 "limit": pagingCount,
  1539.                 "offset": tempOffset
  1540.               };
  1541.               this.loadSqlArticle(tempJson);
  1542.             }
  1543.           }
  1544.         }
  1545.       } else {
  1546.         // console.log("no more data else");
  1547.       }
  1548.     } else {
  1549.       noMoreData = true;
  1550.     }
  1551.   };
  1552.  
  1553.   renderFooter = () => {
  1554.     if (!this.state.footerLoading) return null;
  1555.  
  1556.     return (
  1557.       <View style={styles.loaderIndicator}>
  1558.         <Spinner style={styles.spinner} size={22} type="Circle" color={EStyleSheet.value("$spinner")} />
  1559.       </View>
  1560.     );
  1561.   };
  1562.  
  1563.   gotIt = () => {
  1564.     AsyncStorage.setItem("isFirstTime", "false");
  1565.     this.setState({ loadHint: false })
  1566.   }
  1567.  
  1568.   renderEmpty = () => {
  1569.     if (imagePath == undefined) {
  1570.       imagePath = imageJson.collection_empty;
  1571.       title = translate("ARTICLES_EMPTY1")
  1572.       text = ""
  1573.       links = [{ name: translate("ERESOURCES"), onPressFun: this.openEResources.bind(this) }, { name: translate("WEB"), onPressFun: this.openWeb.bind(this) }];
  1574.       isLink = true;
  1575.     }
  1576.     return (
  1577.       <View>
  1578.         {this.state.errorLoading ?
  1579.           <View>
  1580.             <EmptyScreen
  1581.               imagePath={graphError && graphError.success == undefined ? imageJson.httpError_img : imageJson.something_wrong_here}
  1582.               Title={graphError ? graphError.shortDesc : translate("TECHNICAL_EMPTY")}
  1583.               Text={graphError ? graphError.desc : translate("TECHNICAL_EMPTY_DATA1")}
  1584.               isButton={true}
  1585.               buttonText={translate("SU_EMPTY")}
  1586.               buttonCallback={this.buttonCallback}
  1587.             />
  1588.           </View>
  1589.           :
  1590.           this.state.isFilter ?
  1591.             <View>
  1592.               <EmptyScreen
  1593.                 imagePath={imageJson.no_search_result}
  1594.                 Title={translate("COL_FILTER_EMPTY")}
  1595.                 Text={translate("COL_FILTER_EMPTY_DATA")}
  1596.               />
  1597.             </View>
  1598.             :
  1599.             <View>
  1600.               <EmptyScreen
  1601.                 imagePath={imagePath}
  1602.                 Title={title}
  1603.                 Text={text}
  1604.                 Links={links}
  1605.                 isLink={isLink}
  1606.               />
  1607.             </View>
  1608.         }
  1609.       </View>
  1610.     );
  1611.   }
  1612.  
  1613.   renderHeader = () => {
  1614.     return (
  1615.       <View style={{ paddingBottom: 16 }}>
  1616.         {this.state.loadHint && varProvider.selectedCollectionName == varProvider.defaultCollectionName &&
  1617.           <View style={styles.hintContainer}>
  1618.             <View style={styles.hintToolTipContainer}>
  1619.               <CustomIcons style={styles.tipPinIcon} name="icon_checkmark_crl" />
  1620.             </View>
  1621.             <View style={styles.hintTextContainer}>
  1622.               <Text style={styles.hintText}>{translate("COLLECTON_TIP")}</Text>
  1623.               <TouchableOpacity onPress={this.gotIt}>
  1624.                 <Text style={[styles.hintText, { color: EStyleSheet.value("$secondary") }]}>{"\n"}{translate("GOT_IT")}</Text>
  1625.               </TouchableOpacity>
  1626.             </View>
  1627.           </View>
  1628.         }
  1629.       </View>
  1630.     )
  1631.   }
  1632.  
  1633.   renderCollectionEmpty = () => {
  1634.     return (
  1635.       <View>
  1636.       </View>
  1637.     );
  1638.   }
  1639.  
  1640.   // open/export pdf function view
  1641.   onOpenWithExternalView() {
  1642.     closeFlag = "externalPdfOpen";
  1643.     this.closeActionSheetModal();
  1644.   }
  1645.  
  1646.  
  1647.   openArticleView(item) {
  1648.     cloneIt = item;
  1649.     const { navigate } = this.props.navigation;
  1650.  
  1651.     if (item.type == "PDF") {
  1652.       var urlMD = MD5.MD5(item.url);
  1653.       var path = RNFetchBlob.fs.dirs.DocumentDir + "/" + urlMD + ".pdf";
  1654.       RNFetchBlob.fs.exists(path).then((exist) => {
  1655.         if (exist) {
  1656.           if (Platform.OS == "android") {
  1657.             navigate("PdfView", { "article": item, "path": path, "isModal": true, "callbackAddTag": this.callbackAddTag, "callbackDeleteArticle": this.callbackDeleteArticle, "refScreen": screenNames.Collections });
  1658.           } else {
  1659.             // let aPDFpath = urlMD + ".pdf"
  1660.             var pdfObject = MVMyloftPDFViewerNativeModuleIos.openViewer(item.url, item.id);
  1661.             this.iosPdfEvent(pdfObject);
  1662.           }
  1663.           varProvider.currentScreen = screenNames.PDFView;
  1664.           this.logPdfScreenViewEvent(false);
  1665.           this.updateReadStatus(item);
  1666.           this.logArticleReadEvent(item);
  1667.         }
  1668.         else {
  1669.           Toast.showShortCenter(translate("PDF_NA"));
  1670.         }
  1671.       });
  1672.     } else {
  1673.       if (item.isReadable) {
  1674.         navigate('ArticleView', { "article": item, "callbackAddTag": this.callbackAddTag, "callbackDeleteArticle": this.callbackDeleteArticle, "callbackRead": this.callbackRead, "isModal": true, "refScreen": screenNames.Collections });
  1675.       }
  1676.       else {
  1677.         if (connection.isConnectedFun()) {
  1678.           navigate("BrowserView", { url: item.url, "refScreen": screenNames.Collections });
  1679.           this.updateReadStatus(item);
  1680.         }
  1681.         else {
  1682.           Toast.showShortCenter(translate("PLEASE_CONNECT"));
  1683.         }
  1684.       }
  1685.     }
  1686.   }
  1687.  
  1688.   logPdfScreenViewEvent(isNavigatingBack) {
  1689.     let screenViewJson = {
  1690.       "name": isNavigatingBack ? screenNames.Collections : screenNames.PDFView,
  1691.       "previous": isNavigatingBack ? screenNames.PDFView : screenNames.Collections
  1692.     };
  1693.     analyticsProvider.logAnalyticsJson("ScreenView", screenViewJson);
  1694.   }
  1695.  
  1696.   logArticleReadEvent(item) {
  1697.     let articleReadJson = {
  1698.       "name": item.title,
  1699.       "url": item.url,
  1700.       "type": item.type,
  1701.       "source": "Collections"
  1702.     };
  1703.     analyticsProvider.logAnalyticsJson("ArticleRead", articleReadJson);
  1704.   }
  1705.  
  1706.   iosPdfEvent(pdfObject) {
  1707.  
  1708.     const getAllTagSubscription = pdfObject.addListener(
  1709.       'GetAllTags',
  1710.       () => {
  1711.         colProvider.getTagList().subscribe((data) => {
  1712.           MVMyloftPDFViewerNativeModuleIos.refreshAllTagList(data);
  1713.         });
  1714.       }
  1715.     );
  1716.  
  1717.     const getTagSubscription = pdfObject.addListener(
  1718.       'GetTags',
  1719.       () => {
  1720.         MVMyloftPDFViewerNativeModuleIos.refreshTagList(cloneIt.tagList);
  1721.       }
  1722.     );
  1723.  
  1724.     const getHighlightSubscription = pdfObject.addListener(
  1725.       'GetHighlights',
  1726.       () => {
  1727.  
  1728.         var tempList = {};
  1729.         tempList["articleId"] = cloneIt.id;
  1730.         colProvider.getArticleHighlightList(tempList).subscribe((data) => {
  1731.           var aNewData = [];
  1732.           for (var key in data) {
  1733.             let aData = data[key];
  1734.             aData.text = aData.highlightText;
  1735.             aData.rangyid = aData.rangyId;
  1736.             aData.createdAt = new Date(aData.createdAt).toISOString();
  1737.             aNewData.push(aData);
  1738.           }
  1739.           MVMyloftPDFViewerNativeModuleIos.refreshHighlightList(aNewData);
  1740.         });
  1741.       }
  1742.     );
  1743.  
  1744.     const addTagSubscription = pdfObject.addListener(
  1745.       'AddTags',
  1746.       (addTagObject) => {
  1747.         this.addTagToPdf(addTagObject);
  1748.       }
  1749.     );
  1750.  
  1751.     const highlightAddSubscription = pdfObject.addListener(
  1752.       'HighlightAdded',
  1753.       (highlightObject) => {
  1754.         this.addHighlightToPdf(highlightObject);
  1755.         this.logArticleHighlightEvent();
  1756.       }
  1757.     );
  1758.  
  1759.     const highlightDelSubscription = pdfObject.addListener(
  1760.       'HighlightDeleted',
  1761.       (highlightObject) => {
  1762.         this.deleteHighlightFromPdf(highlightObject);
  1763.       }
  1764.     );
  1765.  
  1766.     const viewerDismissedSubscription = pdfObject.addListener(
  1767.       'ViewerWillDismiss',
  1768.       () => {
  1769.         // console.log("ViewerWillDismiss Collection screen");
  1770.         // console.log(highlightObject);
  1771.         varProvider.isPDFOpen = false;
  1772.         getAllTagSubscription.remove();
  1773.         getTagSubscription.remove();
  1774.         getHighlightSubscription.remove();
  1775.         addTagSubscription.remove();
  1776.         highlightAddSubscription.remove();
  1777.         highlightDelSubscription.remove();
  1778.         viewerDismissedSubscription.remove();
  1779.         deletePDFSubscription.remove();
  1780.         this.logPdfScreenViewEvent(true);
  1781.         varProvider.currentScreen = screenNames.Collections;
  1782.       }
  1783.     );
  1784.  
  1785.     const deletePDFSubscription = pdfObject.addListener(
  1786.       'DeletePDFArticle',
  1787.       () => {
  1788.         MVMyloftPDFViewerNativeModuleIos.closeViewer();
  1789.         setTimeout(() => {
  1790.           this.onDeleteArticle();
  1791.         }, 100)
  1792.       }
  1793.     );
  1794.   }
  1795.  
  1796.   logArticleHighlightEvent() {
  1797.     let articleHighlightJson = {
  1798.       "type": "PDF"
  1799.     };
  1800.     analyticsProvider.logAnalyticsJson("ArticleHighlight", articleHighlightJson)
  1801.   }
  1802.  
  1803.   addTagToPdf(addTagObject) {
  1804.     if (addTagObject && addTagObject["AddTags"]) {
  1805.       var tagNames = addTagObject["AddTags"]["tagNames"];
  1806.       var tagIds = addTagObject["AddTags"]["tags"];
  1807.       var articleTagNames = addTagObject["AddTags"]["articleTags"];
  1808.  
  1809.       var analyticsTags = [];
  1810.       if (cloneIt && cloneIt.tagList && cloneIt.tagList.length != 0) {
  1811.         var existingTags = cloneIt.tagList;
  1812.         for (var k = 0; k < articleTagNames.length; k++) {
  1813.           if (existingTags.indexOf(articleTagNames[k]) == -1) {
  1814.             analyticsTags.push(articleTagNames[k]);
  1815.           }
  1816.         }
  1817.       } else {
  1818.         analyticsTags = articleTagNames;
  1819.       }
  1820.  
  1821.       this.callbackAddTag(articleTagNames);
  1822.  
  1823.       if (tagNames.length != 0 || tagIds.length != 0) {
  1824.         var randomId = [];
  1825.         for (var i = 0; i < tagNames.length; i++) {
  1826.           randomId.push("");
  1827.         }
  1828.         var tempList = {};
  1829.         tempList["articleId"] = cloneIt.id;
  1830.         tempList["tagName"] = tagNames;
  1831.         tempList["tagId"] = tagIds;
  1832.         tempList["randomId"] = randomId;
  1833.         // console.log(tempList);
  1834.         colProvider.addArticleTags(tempList).subscribe(() => {
  1835.         });
  1836.         this.logTagSaveEvent(analyticsTags, "AddTags");
  1837.       }
  1838.       var deleteIds = addTagObject["AddTags"]["deletedTags"];
  1839.       if (deleteIds.length != 0) {
  1840.         var tempList1 = {};
  1841.         tempList1["articleId"] = cloneIt.id;
  1842.         tempList1["tagId"] = deleteIds;
  1843.         // console.log(tempList1);
  1844.         colProvider.deleteArticleTags(tempList1).subscribe(() => {
  1845.         });
  1846.       }
  1847.     }
  1848.   }
  1849.  
  1850.   logTagSaveEvent(name, source) {
  1851.     let tagSaveJson = {
  1852.       "name": name.toString(),
  1853.       "source": source
  1854.     }
  1855.     analyticsProvider.logAnalyticsJson("TagSave", tagSaveJson);
  1856.   }
  1857.  
  1858.   addHighlightToPdf(highlightObject) {
  1859.     if (highlightObject && highlightObject["HighlightAdded"]) {
  1860.       var hjson = highlightObject["HighlightAdded"];
  1861.       var jsonData = [];
  1862.       jsonData.push({
  1863.         "start": 0,
  1864.         "end": 0,
  1865.         "root": hjson["root"],
  1866.         "text": hjson["text"],
  1867.         "class": "myloft_highlight",
  1868.         "rangyid": hjson["rangyid"]
  1869.       });
  1870.  
  1871.       var highId = apiProvider.generateUUID();
  1872.       var randomId = [];
  1873.       randomId.push(highId);
  1874.       var tempList = {};
  1875.       tempList["articleId"] = cloneIt.id;
  1876.       tempList["highlightData"] = jsonData;
  1877.       tempList["randomId"] = randomId;
  1878.       colProvider.addArticleHighlight(tempList).subscribe((data) => {
  1879.         MVMyloftPDFViewerNativeModuleIos.refreshHighlightList(data);
  1880.       });
  1881.     }
  1882.  
  1883.   }
  1884.  
  1885.   deleteHighlightFromPdf(highlightObject) {
  1886.     if (highlightObject && highlightObject["HighlightDeleted"]) {
  1887.       var hjson = highlightObject["HighlightDeleted"];
  1888.       var tempList = {};
  1889.       var hid = [];
  1890.       hid.push(hjson.id);
  1891.       tempList["articleId"] = cloneIt.id;
  1892.       tempList["highlightId"] = hid;
  1893.  
  1894.       colProvider.deleteArticleHighlight(tempList).subscribe(() => {
  1895.       });
  1896.     }
  1897.   }
  1898.  
  1899.   updateReadStatus(articleItem) {
  1900.     if (!articleItem.readStatus) {
  1901.       articleItem.readStatus = true;
  1902.       colProvider.readArticle(articleItem).subscribe(() => {
  1903.       });
  1904.       this.setState({ refresh: !this.state.refresh });
  1905.     }
  1906.   }
  1907.  
  1908.   closeGuide = () => {
  1909.     this.setState({ showGuide: false })
  1910.     setProvider.closeGuide("isCollectionsGuideShown");
  1911.   }
  1912.  
  1913.   _renderListView = ({ item }) => (
  1914.     <ArticleListNewView
  1915.       id={item.id}
  1916.       title={item.title}
  1917.       timeAgo={item.timeAgo}
  1918.       readStatus={item.readStatus}
  1919.       hostname={item.hostname}
  1920.       bgColor={item.bgColor}
  1921.       image={item.image}
  1922.       tagList={item.tagList}
  1923.       isFavorite={item.isFavorite}
  1924.       isPDFAvailable={item.isPDFAvailable}
  1925.       data={item}
  1926.       openArticleView={this.openArticleView}
  1927.       favoriteArticle={this.favoriteArticle}
  1928.       openModal={this.openModal}
  1929.       navigation={this.props.navigation}
  1930.       openTagModal={this.openTagModal}
  1931.     />
  1932.   );
  1933.  
  1934.   _renderCardView = ({ item, index }) => (
  1935.     <ArticleCardNewView
  1936.       id={item.id}
  1937.       title={item.title}
  1938.       timeAgo={item.timeAgo}
  1939.       readStatus={item.readStatus}
  1940.       hostname={item.hostname}
  1941.       bgColor={item.bgColor}
  1942.       image={item.image}
  1943.       tagList={item.tagList}
  1944.       isFavorite={item.isFavorite}
  1945.       shouldDisplayCollection={false}
  1946.       cardWidth={cardWidth}
  1947.       numberOfCards={numberOfCards}
  1948.       cardLeftWidth={cardLeftWidth}
  1949.       isPDFAvailable={item.isPDFAvailable}
  1950.       data={item}
  1951.       openArticleView={this.openArticleView}
  1952.       favoriteArticle={this.favoriteArticle}
  1953.       openModal={this.openModal}
  1954.       navigation={this.props.navigation}
  1955.       index={index}
  1956.     />
  1957.   );
  1958.  
  1959.   openTagModal = (item) => {
  1960.     tagList = [];
  1961.     if (item.tagList?.length > 0)
  1962.       tagList = item.tagList;
  1963.     this.setState({ openTagModal: true })
  1964.   }
  1965.  
  1966.   childResponser = () => {
  1967.     startParentResponderTouch = false;
  1968.     startChildResponderTouch = true;
  1969.   }
  1970.  
  1971.   parentResponser = () => {
  1972.     if (startParentResponderTouch) {
  1973.       if (startChildResponderTouch)
  1974.         startChildResponderTouch = false;
  1975.       else
  1976.         this.closeEditMode();
  1977.     }
  1978.     else {
  1979.       startParentResponderTouch = true;
  1980.     }
  1981.   }
  1982.  
  1983.   render() {
  1984.     var renderFavArticleFooter =
  1985.       <TouchableOpacity
  1986.         activeOpacity={0.7}
  1987.         style={drawerStyles.favMenuItem}
  1988.         onPress={() => this.menuItemPress(favoriteArticles)}
  1989.       >
  1990.         <View style={drawerStyles.menuLeftIconView}>
  1991.           <CustomIcons style={[drawerStyles.menuLeftIcon, favoriteArticles.active && drawerStyles.menuLeftIconActive]} name="icon_fav_content" />
  1992.         </View>
  1993.         <Text style={[drawerStyles.menuItemText, favoriteArticles.active && drawerStyles.menuItemTextDefault]}>{favoriteArticles.title}</Text>
  1994.         <View style={drawerStyles.menuItemRightView}>
  1995.         </View>
  1996.       </TouchableOpacity>;
  1997.  
  1998.     var menu =
  1999.       <SafeAreaView
  2000.         edges={["left", "top", "right"]}
  2001.         style={drawerStyles.mainContainer}>
  2002.         <View style={drawerStyles.headerContainer}>
  2003.           <View style={drawerStyles.headerTop}>
  2004.             <Text style={drawerStyles.headerTopLeft}>{translate("COLLECTIONS")}
  2005.             </Text>
  2006.             <View style={drawerStyles.headerTopRight}>
  2007.               <TouchableOpacity activeOpacity={0.5} style={drawerStyles.headerIconContainer} onPress={() => this.addCollection()}>
  2008.                 <CustomIcons style={drawerStyles.headerIcon} name="icon_add_new_collection" />
  2009.               </TouchableOpacity>
  2010.             </View>
  2011.           </View>
  2012.  
  2013.         </View>
  2014.         {this.state.noData ?
  2015.           <View>
  2016.             <Text style={drawerStyles.noSearchResult}>{translate("SEARCH_EMPTY")}</Text>
  2017.           </View>
  2018.           :
  2019.           <View style={{ flex: 1 }}>
  2020.             <FlatList
  2021.               data={filteredColList}
  2022.               extraData={this.state.refreshCollection}
  2023.               ListEmptyComponent={this.renderCollectionEmpty}
  2024.               renderItem={({ item }) =>
  2025.                 <View>
  2026.                   <TouchableOpacity
  2027.                     activeOpacity={0.7}
  2028.                     key={item.id}
  2029.                     style={[drawerStyles.menuItem, item.pressed && drawerStyles.menuItemPressed]}
  2030.                     onLongPress={() => { this.menuItemLongPress(item) }}
  2031.                     onPress={() => this.menuItemPress(item)}
  2032.                   >
  2033.                     <View style={drawerStyles.menuLeftIconView}>
  2034.                       <CustomIcons style={[drawerStyles.menuLeftIcon, item.active && drawerStyles.menuLeftIconActive]} name={item.title === "General Collection" ? "icon_collection_folder" : "icon_user_folder"} />
  2035.                     </View>
  2036.                     <Text style={[drawerStyles.menuItemText, item.active && drawerStyles.menuItemTextDefault]}>{item.title}</Text>
  2037.                     <View style={drawerStyles.menuItemRightView}>
  2038.                       {item.isDefault &&
  2039.                         <CustomIcons style={[drawerStyles.menuItemIcon, item.active && drawerStyles.menuItemSelectedIcon]} name="icon_checkmark_crl" />
  2040.                       }
  2041.                     </View>
  2042.                   </TouchableOpacity>
  2043.                   {item.pressed &&
  2044.                     <View style={drawerStyles.menuItemPressedView}>
  2045.                       <View style={drawerStyles.gradientView}>
  2046.                         <LinearGradient
  2047.                           start={{ x: 0, y: 0 }}
  2048.                           end={{ x: 1, y: 0 }}
  2049.                           locations={[0.7, 1]}
  2050.                           colors={["#ffffff00", "#eee"]}
  2051.                           style={drawerStyles.gradientView} />
  2052.                       </View>
  2053.                       <View style={drawerStyles.menuItemActionsView} onTouchStart={() => { this.childResponser() }}>
  2054.                         {this.state.cloneItem.type != staticConfig.collectionType && <TouchableOpacity activeOpacity={0.5} style={drawerStyles.headerIconContainer} onPress={() => this.editTitle()}>
  2055.                           <CustomIcons style={drawerStyles.headerIcon} name="icon_edit" />
  2056.                         </TouchableOpacity>}
  2057.                         {!this.state.cloneItem.isDefault && this.state.cloneItem.type != staticConfig.collectionType && <TouchableOpacity activeOpacity={0.5} style={drawerStyles.headerIconContainer} onPress={() => this.deleteCollection()}>
  2058.                           <CustomIcons style={drawerStyles.headerIcon} name="icon_delete" />
  2059.                         </TouchableOpacity>}
  2060.                         {!this.state.cloneItem.isDefault && <TouchableOpacity activeOpacity={0.5} style={drawerStyles.headerIconContainer} onPress={() => this.setDefaultCollection()}>
  2061.                           <CustomIcons style={drawerStyles.headerIcon} name="icon_checkmark_crl" />
  2062.                         </TouchableOpacity>}
  2063.                         <TouchableOpacity activeOpacity={0.5} style={drawerStyles.headerIconContainer} onPress={() => { this.closeEditMode(); drawerLockMode = "unlocked" }}>
  2064.                           <CustomIcons style={drawerStyles.headerIcon} name="icon_cancel" />
  2065.                         </TouchableOpacity>
  2066.                       </View></View>
  2067.                   }
  2068.                 </View>
  2069.  
  2070.               }
  2071.             />
  2072.             {renderFavArticleFooter}
  2073.           </View>
  2074.         }
  2075.  
  2076.         {this.state.addCollectionModal &&
  2077.           <CustomAlert
  2078.             title={translate("NC_TITLE")}
  2079.             isInput={true}
  2080.             subTitle=""
  2081.             placeholder={translate("ADD_COLLECTION_DATA")}
  2082.             autoFocus={true}
  2083.             inputTextCallback={this.getAddCollectionText}
  2084.             validationText={this.state.addCollectionValidationText}
  2085.             preConfirm={true}
  2086.             isValid={this.state.addCollectionValid}
  2087.             maxLength={config.collectionMax}
  2088.             leftButtonText={translate("ALERT_CANCEL")}
  2089.             rightButtonText={translate("ALERT_SAVE")}
  2090.             closeCallback={this.closeAddCollectionModal}
  2091.             leftButtonCallback={this.closeAddCollectionModal}
  2092.             rightButtonCallback={this.onSaveAddCollection}
  2093.             swidth={screenWidth}
  2094.           />
  2095.         }
  2096.  
  2097.         {this.state.editTitleCollectionModal &&
  2098.           <CustomAlert
  2099.             title={translate("RENAME_COLLECTION")}
  2100.             subTitle=""
  2101.             placeholder={translate("RENAME_COLLECTION_DATA")}
  2102.             isInput={true}
  2103.             initialValue={this.state.initialValue}
  2104.             autoFocus={true}
  2105.             inputTextCallback={this.getEditTitleCollectionText}
  2106.             validationText={this.state.editTitleCollectionValidationText}
  2107.             preConfirm={true}
  2108.             isValid={this.state.editTitleCollectionValid}
  2109.             maxLength={config.collectionMax}
  2110.             leftButtonText={translate("ALERT_CANCEL")}
  2111.             rightButtonText={translate("ALERT_SAVE")}
  2112.             closeCallback={this.closeEditTitleCollectionModal}
  2113.             leftButtonCallback={this.closeEditTitleCollectionModal}
  2114.             rightButtonCallback={this.onSaveEditTitleCollection}
  2115.             swidth={screenWidth}
  2116.           />
  2117.         }
  2118.  
  2119.         {this.state.deleteCollectionModal &&
  2120.           <CustomAlert
  2121.             title={translate("DELETE_COLLECTION")}
  2122.             subTitle={translate("DELETE_COLLECTION_DATA")}
  2123.             leftButtonText={translate("ALERT_CANCEL")}
  2124.             rightButtonText={translate("ALERT_DELETE")}
  2125.             closeCallback={this.closeDeleteCollectionModal}
  2126.             leftButtonCallback={this.closeDeleteCollectionModal}
  2127.             rightButtonCallback={this.onDeleteCollection}
  2128.             swidth={screenWidth}
  2129.           />
  2130.         }
  2131.  
  2132.  
  2133.         {this.state.openTagModal && tagList?.length > 0 ?
  2134.           <TagBottomSheet
  2135.             tagList={tagList}
  2136.             hideCallback={this.closeTagBottomSheet}
  2137.             modalWidth={modalWidth}
  2138.             modalHeight={modalHeight} /> : null}
  2139.  
  2140.         <GuideView slides={guideImageJson.Collections} screen={"Collections"} showGuide={this.state.showGuide} closeGuide={this.closeGuide} />
  2141.       </SafeAreaView>;
  2142.  
  2143.     var headerBar =
  2144.  
  2145.       <View style={Platform.OS === 'ios' ? styles.newHeaderContainer : styles.newHeaderContainerAndroid}>
  2146.         <View style={Platform.OS === 'ios' ? styles.newTopHeaderContainer : styles.newTopHeaderContainerAndroid}>
  2147.           <TouchableOpacity activeOpacity={0.7} style={styles.newMenuButtonContainer} onPress={() => this.openMenu()}>
  2148.             <CustomIcons style={styles.newMenuButtonIcon} name="icon_side_menu" />
  2149.             <View style={styles.newMenuButtonRedDot}><View style={styles.newMenuButtonRedDotChild}></View></View>
  2150.           </TouchableOpacity>
  2151.           <View style={styles.newHeaderLeftButtonView}>
  2152.             <Text style={styles.newHeaderLeftButtonText} numberOfLines={1}>{varProvider.selectedCollectionName}</Text>
  2153.           </View>
  2154.           <TouchableOpacity activeOpacity={0.5} disabled={this.state.articleLength == 0} style={[styles.newHeaderRightButtonView, styles.newHeaderSecondRightButtonView]} onPress={() => this.changeView()}>
  2155.             <CustomIcons style={[styles.newHeaderRightButtonIcon, this.state.articleLength == 0 && { color: EStyleSheet.value("$disableIcon") }]} name={this.state.isCardView ? "icon_list_view" : "icon_card_view"} />
  2156.           </TouchableOpacity>
  2157.           <TouchableOpacity activeOpacity={0.5} disabled={this.state.articleLength == 0 && !this.state.isFilter} style={styles.newHeaderRightButtonView} onPress={() => this.openFilters()}>
  2158.             <CustomIcons style={[styles.newHeaderRightButtonIcon, this.state.articleLength == 0 && !this.state.isFilter && { color: EStyleSheet.value("$disableIcon") }]} name="icon_filter" />
  2159.           </TouchableOpacity>
  2160.         </View>
  2161.       </View>
  2162.  
  2163.     return (
  2164.       <View style={{ flex: 1 }} onTouchStart={() => { this.parentResponser() }}>
  2165.         <DrawerLayout
  2166.           drawerWidth={300}
  2167.           // useNativeAnimations={true}
  2168.           drawerBackgroundColor="white"
  2169.           ref={(_drawer) => { this.drawer = _drawer; varProvider.colDrawer = _drawer; }}
  2170.           onDrawerClose={() => { this.onDrawerClose() }}
  2171.           drawerPosition={DrawerLayout.positions.Left}
  2172.           drawerLockMode={drawerLockMode}
  2173.           renderNavigationView={() => menu}>
  2174.           <SafeAreaView
  2175.             edges={["left", "top", "right"]}
  2176.             style={{ backgroundColor: "#fff", flex: 1 }}>
  2177.  
  2178.             {headerBar}
  2179.  
  2180.             <View style={styles.mainContainer}>
  2181.  
  2182.               <View>
  2183.                 <ScrollView style={styles.chipScrollView} horizontal={true}>
  2184.                   {this.state.activeFilters.map((item, key) =>
  2185.                   (
  2186.                     <View key={key}>
  2187.                       {item.chipTitle == "tagName" ?
  2188.                         <View style={{ flexDirection: 'row' }}>
  2189.                           {item.value.map((subItem) =>
  2190.                           (
  2191.                             <View key={subItem}>
  2192.                               <Chip
  2193.                                 rootStyle={styles.chipContainer}
  2194.                                 chipTitle={subItem}
  2195.                                 removeCallback={() => this.removeFilter(subItem, true)}
  2196.                               />
  2197.                             </View>
  2198.                           ))
  2199.                           }
  2200.                         </View>
  2201.                         :
  2202.                         <View>
  2203.                           {item.active &&
  2204.                             <Chip
  2205.                               rootStyle={styles.chipContainer}
  2206.                               chipTitle={item.chipTitle}
  2207.                               removeCallback={() => this.removeFilter(item)}
  2208.                             />
  2209.                           }
  2210.                         </View>
  2211.                       }
  2212.                     </View>
  2213.                   ))
  2214.                   }
  2215.                 </ScrollView>
  2216.               </View>
  2217.  
  2218.               {this.state.articleLoading &&
  2219.                 <ArticleLoader />
  2220.               }
  2221.  
  2222.               {!this.state.isCardView && !this.state.articleLoading &&
  2223.                 <FlatList
  2224.                   bounces={articleList.length == 0 ? false : true}
  2225.                   style={{ marginBottom: 0 }}
  2226.                   contentContainerStyle={[{ paddingBottom: 8 }, articleList.length == 0 && { justifyContent: this.state.loadHint && varProvider.selectedCollectionName == varProvider.defaultCollectionName ? 'flex-start' : 'center', height: this.state.loadHint && varProvider.selectedCollectionName == varProvider.defaultCollectionName ? "120%" : "100%" }]}
  2227.                   data={articleList}
  2228.                   extraData={this.state.refresh}
  2229.                   ListFooterComponent={this.renderFooter}
  2230.                   ListEmptyComponent={this.renderEmpty}
  2231.                   ListHeaderComponent={this.renderHeader}
  2232.                   onEndReached={this.handleLoadMore}
  2233.                   onEndReachedThreshold={0.5}
  2234.                   renderItem={this._renderListView}
  2235.                 />
  2236.               }
  2237.  
  2238.               {this.state.isCardView && !this.state.articleLoading &&
  2239.                 <FlatList
  2240.                   bounces={articleList.length == 0 ? false : true}
  2241.                   style={{ marginBottom: 0 }}
  2242.                   contentContainerStyle={[{ paddingBottom: 8 }, articleList.length == 0 && { justifyContent: this.state.loadHint && varProvider.selectedCollectionName == varProvider.defaultCollectionName ? 'flex-start' : 'center', height: this.state.loadHint && varProvider.selectedCollectionName == varProvider.defaultCollectionName ? "120%" : "100%" }]}
  2243.                   data={articleList}
  2244.                   columnWrapperStyle={numberOfCards > 1 && { marginHorizontal: 8 }}
  2245.                   extraData={this.state.refresh}
  2246.                   numColumns={numberOfCards}
  2247.                   key={numberOfCards}
  2248.                   ListFooterComponent={this.renderFooter}
  2249.                   ListEmptyComponent={this.renderEmpty}
  2250.                   ListHeaderComponent={this.renderHeader}
  2251.                   onEndReached={this.handleLoadMore}
  2252.                   onEndReachedThreshold={0.5}
  2253.                   renderItem={this._renderCardView}
  2254.                 />
  2255.               }
  2256.  
  2257.               <ActionSheet
  2258.                 isVisible={this.state.actionSheetModal}
  2259.                 closeCallback={this.closeActionSheetModal}
  2260.                 hideCallback={this.hideActionSheetModal}
  2261.                 modalWidth={modalWidth}
  2262.                 modalHeight={modalHeight}
  2263.                 backdropColor="#333"
  2264.                 backdropOpacity={0.3}
  2265.                 data={this.state.asList}
  2266.               />
  2267.  
  2268.               <ShareActionSheet
  2269.                 backdropColor="#333"
  2270.                 backdropOpacity={0.3}
  2271.                 isVisible={this.state.sharedOpened}
  2272.                 hideCallback={this.hideActionSheetModal}
  2273.                 onBackButtonPress={() => { this.setState({ sharedOpened: false }) }}
  2274.                 onBackdropPress={() => { this.setState({ sharedOpened: false }) }}
  2275.                 modalHeight={modalHeight}
  2276.                 modalWidth={modalWidth}
  2277.                 sendTo={this.sendTo.bind(this)}
  2278.                 shareNativeArticle={this.shareNativeArticle.bind(this)}
  2279.                 isConnected={connection.isConnectedFun()}
  2280.               />
  2281.  
  2282.               {this.state.editTitleModal &&
  2283.                 <CustomAlert
  2284.                   title={translate("ARTICLE_RENAME")}
  2285.                   subTitle=""
  2286.                   placeholder={translate("ARTICLE_RENAME_DATA")}
  2287.                   isInput={true}
  2288.                   initialValue={this.state.initialValue}
  2289.                   autoFocus={true}
  2290.                   inputTextCallback={this.getEditTitleText}
  2291.                   validationText={this.state.editTitleValidationText}
  2292.                   preConfirm={true}
  2293.                   maxLength={config.articleTitleMax}
  2294.                   isValid={this.state.editTitleValid}
  2295.                   leftButtonText={translate("ALERT_CANCEL")}
  2296.                   rightButtonText={translate("ALERT_SAVE")}
  2297.                   closeCallback={this.closeEditTitleModal}
  2298.                   leftButtonCallback={this.closeEditTitleModal}
  2299.                   rightButtonCallback={this.onSaveEditTitle}
  2300.                   swidth={screenWidth}
  2301.                 />
  2302.               }
  2303.  
  2304.               {this.state.deleteArticleModal &&
  2305.                 <CustomAlert
  2306.                   title={translate("DELETE_ARTICLE")}
  2307.                   subTitle={translate("DELETE_ARTICLE_DATA")}
  2308.                   leftButtonText={translate("ALERT_CANCEL")}
  2309.                   rightButtonText={translate("ALERT_DELETE")}
  2310.                   closeCallback={this.closeDeleteArticleModal}
  2311.                   leftButtonCallback={this.closeDeleteArticleModal}
  2312.                   rightButtonCallback={this.onDeleteArticle}
  2313.                   swidth={screenWidth}
  2314.                 />
  2315.               }
  2316.  
  2317.             </View>
  2318.           </SafeAreaView>
  2319.         </DrawerLayout>
  2320.       </View>
  2321.     );
  2322.   }
  2323.  
  2324.   removeFilter(item, isTag) {
  2325.     var tempFilters = this.state.activeFilters;
  2326.     if (isTag) {
  2327.       var tagList = tempFilters[4].value;
  2328.       for (var i = 0; i < tagList.length; i++) {
  2329.         if (item == tagList[i]) {
  2330.           tempFilters[4].value.splice(i, 1);
  2331.           if (tempFilters[4].value.length == 0) {
  2332.             tempFilters[4].active = false;
  2333.           }
  2334.           break;
  2335.         }
  2336.       }
  2337.     } else {
  2338.       for (var i = 0; i < tempFilters.length; i++) {
  2339.         if (item.chipTitle == tempFilters[i].chipTitle) {
  2340.           tempFilters[i].active = false;
  2341.           break;
  2342.         }
  2343.       }
  2344.     }
  2345.  
  2346.     this.callbackFun(tempFilters);
  2347.   }
  2348.  
  2349.   closeActionSheetModal() {
  2350.     this.setState({ actionSheetModal: false });
  2351.   }
  2352.  
  2353.  
  2354.   // here we get callback that action sheet/share action sheet is closed, now we can perform action according to value of closeFlag
  2355.   hideActionSheetModal() {
  2356.     if (closeFlag == "editArticle") {
  2357.       this.setState({ editTitleModal: true });
  2358.     }
  2359.     else if (closeFlag == "deleteArticle") {
  2360.       this.setState({ deleteArticleModal: true });
  2361.     }
  2362.     else if (closeFlag == "actionSheet") {
  2363.       this.setState({ sharedOpened: true });
  2364.     }
  2365.     else if (closeFlag == "externalPdfOpen") {
  2366.       colProvider.onOpenWithExternalView(this.props.navigation, cloneIt)
  2367.     }
  2368.     else if (closeFlag == "shareVia") {
  2369.       setTimeout(() => {
  2370.         if (Platform.OS == "ios") {
  2371.           Share.share({
  2372.             message: cloneIt.url,
  2373.             url: cloneIt.url,
  2374.             title: cloneIt.title
  2375.           }, {
  2376.             // Android only:
  2377.             dialogTitle: cloneIt.title,
  2378.           }).then(() => {
  2379.             // console.log(data);
  2380.           }).catch(() => {
  2381.             // console.log(err);
  2382.           });
  2383.  
  2384.         } else {
  2385.           ShareIntentModule.openShareIntent(cloneIt.title, cloneIt.url, () => {
  2386.           });
  2387.         }
  2388.       }, 400)
  2389.       this.logShareEvent(cloneIt.url, "Other");
  2390.     }
  2391.     closeFlag = "";
  2392.   }
  2393.  
  2394.   shareArticle() {
  2395.     if (connection.isConnectedFun()) {
  2396.       this.closeActionSheetModal();
  2397.       closeFlag = "actionSheet"
  2398.     } else {
  2399.       Toast.showShortCenter(translate("PLEASE_CONNECT"));
  2400.     }
  2401.   }
  2402.  
  2403.   sendTo() {
  2404.     const { navigate } = this.props.navigation;
  2405.     if (connection.isConnectedFun()) {
  2406.       this.setState({ sharedOpened: false });
  2407.       navigate('ShareArticle', { "article": cloneIt, "isModal": true, "refScreen": screenNames.Collections });
  2408.     } else {
  2409.       Toast.showShortCenter(translate("PLEASE_CONNECT"));
  2410.     }
  2411.   }
  2412.  
  2413.   shareNativeArticle() {
  2414.     if (connection.isConnectedFun()) {
  2415.       closeFlag = "shareVia"
  2416.       this.setState({ sharedOpened: false });
  2417.     }
  2418.     else {
  2419.       Toast.showShortCenter(translate("PLEASE_CONNECT"));
  2420.     }
  2421.   }
  2422.  
  2423.   logShareEvent(url, medium) {
  2424.     let shareJson = {
  2425.       "medium": medium,
  2426.       "url": url
  2427.     };
  2428.     analyticsProvider.logAnalyticsJson("Share", shareJson);
  2429.   }
  2430.  
  2431.   getEditTitleText(e) {
  2432.     this.setState({ editTitleText: e });
  2433.   }
  2434.  
  2435.   onSaveEditTitle() {
  2436.     if (!this.state.editTitleText) {
  2437.       this.setState({ editTitleValid: true, editTitleValidationText: translate("ARTICLE_RENAME_VALIDATION") });
  2438.     } else {
  2439.       var trimmedTitle = this.state.editTitleText.trim();
  2440.       if (trimmedTitle) {
  2441.         cloneIt.title = trimmedTitle;
  2442.  
  2443.         colProvider.editArticle(cloneIt).subscribe(() => {
  2444.         });
  2445.  
  2446.         this.setState({ editTitleValid: false, refresh: !this.state.refresh });
  2447.         this.closeEditTitleModal();
  2448.       } else {
  2449.         this.setState({ editTitleValid: true, editTitleValidationText: translate("ARTICLE_RENAME_VALIDATION") });
  2450.       }
  2451.     }
  2452.   }
  2453.  
  2454.   closeEditTitleModal() {
  2455.     this.setState({ editTitleModal: false })
  2456.   }
  2457.  
  2458.   closeDeleteArticleModal() {
  2459.     this.setState({ deleteArticleModal: false })
  2460.   }
  2461.  
  2462.   onDeleteArticle() {
  2463.     this.closeDeleteArticleModal();
  2464.     //added timeout to remove lag in UI
  2465.     setTimeout(() => {
  2466.       for (var i = 0; i < articleList.length; i++) {
  2467.         if (articleList[i].id == cloneIt.id) {
  2468.           articleList.splice(i, 1);
  2469.           if (articleList.length < pagingCount && !noMoreData) {
  2470.             setTimeout(() => {
  2471.               this.handleLoadMore({ distanceFromEnd: "NeedToFetch" });
  2472.             }, 1000);
  2473.           }
  2474.           break;
  2475.         }
  2476.       }
  2477.  
  2478.       Toast.showShortCenter(translate("ARTICLE_DELETED"));
  2479.  
  2480.       var tempList = [];
  2481.       tempList.push(cloneIt);
  2482.       colProvider.deleteArticle(tempList).subscribe(() => {
  2483.       });
  2484.       this.setState({ refresh: !this.state.refresh });
  2485.     }, 500);
  2486.   }
  2487.  
  2488.   favoriteArticle(item) {
  2489.     if (item.isFavorite) {
  2490.       item.isFavorite = false;
  2491.     }
  2492.     else {
  2493.       item.isFavorite = true;
  2494.     }
  2495.     //if favorite articles is selected then remove the unfavorited article from list
  2496.     if (varProvider.selectedCollectionId == "favoriteArticles")
  2497.       this.removeFromFavorite(item);
  2498.     colProvider.favoriteArticle(item).subscribe(() => {
  2499.     });
  2500.     this.setState({ refresh: !this.state.refresh });
  2501.   }
  2502.  
  2503.   openModal(item) {
  2504.     if (item?.isPDFAvailable == 'false') {
  2505.       asList[0].isGrayedOut = true;
  2506.     } else {
  2507.       asList[0].isGrayedOut = false;
  2508.     }
  2509.  
  2510.     if (item.readStatus) {
  2511.       asList[6].title = translate("MARK_AS") + translate("UNREAD")
  2512.     }
  2513.     else {
  2514.       asList[6].title = translate("MARK_AS") + translate("READ");
  2515.     }
  2516.  
  2517.     if (item.type == "PDF") {
  2518.       asList[1].isVisible = false;
  2519.       asList[0].isVisible = true; //check type is pdf then we will show open with option
  2520.     } else {
  2521.       asList[1].isVisible = true;
  2522.       asList[0].isVisible = false;
  2523.     }
  2524.     this.setState({ asList: asList, actionSheetModal: true });
  2525.     cloneIt = item;
  2526.   }
  2527.  
  2528.  
  2529.   callbackAddTag(tagList) {
  2530.     tagList.sort(colProvider.SortByNameArray);
  2531.     cloneIt.tagList = tagList;
  2532.     this.setState({ refresh: !this.state.refresh });
  2533.   }
  2534.  
  2535.   callbackDeleteArticle() {
  2536.     this.onDeleteArticle();
  2537.   }
  2538.  
  2539.   callbackRead() {
  2540.     cloneIt.readStatus = true;
  2541.     this.setState({ refresh: !this.state.refresh });
  2542.   }
  2543.  
  2544.   callbackCollection() {
  2545.     if (varProvider.selectedCollectionName != translate("FAVORITE_ARTICLES")) {
  2546.       for (var i = 0; i < articleList.length; i++) {
  2547.         if (articleList[i].title == cloneIt.title) {
  2548.           articleList.splice(i, 1);
  2549.           if (articleList.length < pagingCount && !noMoreData) {
  2550.             setTimeout(() => {
  2551.               this.handleLoadMore({ distanceFromEnd: "NeedToFetch" });
  2552.             }, 1000);
  2553.           }
  2554.         }
  2555.       }
  2556.       this.setState({ refresh: !this.state.refresh });
  2557.     }
  2558.   }
  2559.  
  2560.   addTags() {
  2561.     this.closeActionSheetModal();
  2562.     const { navigate } = this.props.navigation;
  2563.     navigate('AddTags', { article: cloneIt, "callbackAddTag": this.callbackAddTag, "isModal": true, "refScreen": screenNames.Collections });
  2564.   }
  2565.  
  2566.   editTitleArticle() {
  2567.     this.closeActionSheetModal();
  2568.     if (Platform.OS == "ios") {
  2569.       this.setState({ initialValue: cloneIt.title, editTitleText: cloneIt.title, editTitleValid: false });
  2570.     }
  2571.     else {
  2572.       this.setState({ editTitleModal: true, initialValue: cloneIt.title, editTitleText: cloneIt.title, editTitleValid: false });
  2573.     }
  2574.     closeFlag = "editArticle";
  2575.   }
  2576.  
  2577.   moveToCollection() {
  2578.     this.closeActionSheetModal();
  2579.     const { navigate } = this.props.navigation;
  2580.     navigate('MoveToCollection', { "isModal": true, collectionList: collectionList, article: cloneIt, "callbackCollection": this.callbackCollection.bind(this), "refScreen": screenNames.Collections });
  2581.   }
  2582.  
  2583.   deleteArticle() {
  2584.     this.closeActionSheetModal();
  2585.     if (Platform.OS == "ios") {
  2586.     }
  2587.     else {
  2588.       this.setState({ deleteArticleModal: true });
  2589.     }
  2590.     closeFlag = "deleteArticle";
  2591.   }
  2592.  
  2593.   markAsRead() {
  2594.     this.closeActionSheetModal();
  2595.     var alertMsg;
  2596.     if (cloneIt.readStatus) {
  2597.       cloneIt.readStatus = false;
  2598.       alertMsg = translate("UNREAD");
  2599.     }
  2600.     else {
  2601.       cloneIt.readStatus = true;
  2602.       alertMsg = translate("READ");
  2603.     }
  2604.  
  2605.     colProvider.readArticle(cloneIt).subscribe(() => {
  2606.     });
  2607.     this.setState({ refresh: !this.state.refresh });
  2608.   }
  2609.  
  2610.  
  2611.   //collection side menu functions
  2612.   closeEditMode() {
  2613.     if (cloneIt) {
  2614.       cloneIt.pressed = false;
  2615.     }
  2616.     setTimeout(() => {
  2617.       isEditMode = false;
  2618.       drawerLockMode = "unlocked"
  2619.     }, 200)
  2620.     this.setState({ editMode: false, refreshCollection: !this.state.refreshCollection });
  2621.   }
  2622.  
  2623.   setDefaultCollection() {
  2624.     for (var i = 0; i < collectionList.length; i++) {
  2625.       if (collectionList[i].isDefault) {
  2626.         collectionList[i].isDefault = false;
  2627.       }
  2628.     }
  2629.     cloneIt.isDefault = true;
  2630.     cloneIt.pressed = false;
  2631.  
  2632.     collectionList.sort(colProvider.SortByName);
  2633.  
  2634.     //add collection marked as default to front
  2635.     for (var j = 0; j < collectionList.length; j++) {
  2636.       if (collectionList[j].id == cloneIt.id) {
  2637.         collectionList.splice(j, 1);
  2638.         collectionList.unshift(cloneIt);
  2639.         break;
  2640.       }
  2641.     }
  2642.  
  2643.     varProvider.defaultCollectionId = cloneIt.id;
  2644.     varProvider.defaultCollectionName = cloneIt.title;
  2645.     varProvider.defaultCollectionType = cloneIt.type;
  2646.     AsyncStorage.multiSet([
  2647.       ["defaultCollectionId", varProvider.defaultCollectionId],
  2648.       ["defaultCollectionName", varProvider.defaultCollectionName],
  2649.       ["defaultCollectionType", varProvider.defaultCollectionType]
  2650.     ]);
  2651.     colProvider.setDefaultCollection(cloneIt).subscribe(() => {
  2652.     });
  2653.     this.logCollectionUpdateEvent(cloneIt.title);
  2654.     isEditMode = false;
  2655.     drawerLockMode = "unlocked"
  2656.     this.setState({ editMode: false, refreshCollection: !this.state.refreshCollection });
  2657.   }
  2658.  
  2659.   logCollectionUpdateEvent(name) {
  2660.     let collectionUpdateJson = {
  2661.       "name": name
  2662.     };
  2663.     analyticsProvider.logAnalyticsJson("CollectionUpdate", collectionUpdateJson)
  2664.   }
  2665.  
  2666.   addCollection() {
  2667.     if (isEditMode) {
  2668.       this.closeEditMode();
  2669.     }
  2670.     else {
  2671.       this.setState({ addCollectionModal: true, addCollectionText: "", addCollectionValid: false });
  2672.     }
  2673.   }
  2674.  
  2675.   getAddCollectionText(e) {
  2676.     this.setState({ addCollectionText: e });
  2677.   }
  2678.  
  2679.   closeAddCollectionModal() {
  2680.     this.setState({ addCollectionModal: false });
  2681.   }
  2682.  
  2683.   onSaveAddCollection() {
  2684.     if (!this.state.addCollectionText) {
  2685.       this.setState({ addCollectionValid: true, addCollectionValidationText: translate("NC_EMPTY") });
  2686.     }
  2687.     else {
  2688.       var trimmedTitle = this.state.addCollectionText.trim();
  2689.       if (trimmedTitle) {
  2690.         if (config.collectionRegex.test(trimmedTitle)) {
  2691.           var flagCollection = false;
  2692.           for (var i = 0; i < collectionList.length; i++) {
  2693.             if (collectionList[i].title.toLowerCase() == trimmedTitle.toLowerCase()) {
  2694.               flagCollection = true;
  2695.             }
  2696.           }
  2697.           if (trimmedTitle.toLowerCase() == translate("FAVORITE_ARTICLES").toLowerCase()) {
  2698.             flagCollection = true;
  2699.           }
  2700.           if (flagCollection) {
  2701.             this.setState({ addCollectionValid: true, addCollectionValidationText: translate("NC_EXIST") });
  2702.           } else {
  2703.             var uuid = apiProvider.generateUUID();
  2704.             var title = trimmedTitle;
  2705.             var updatedAt = new Date().getTime();
  2706.             var tempColList = JSON.parse(JSON.stringify(collectionList));
  2707.             tempColList.splice(0, 1);
  2708.             var toInsertIndex = colProvider.getSortedIndex(tempColList, title, "title");
  2709.             collectionList.splice(toInsertIndex + 1, 0, {
  2710.               "id": uuid,
  2711.               "title": title,
  2712.               "description": "",
  2713.               "isDefault": false,
  2714.               "createdAt": updatedAt,
  2715.               "updatedAt": updatedAt,
  2716.               "pressed": false,
  2717.               "active": false
  2718.             });
  2719.  
  2720.             colProvider.addCollection(uuid, title, updatedAt).subscribe((data) => {
  2721.               varProvider.newAddedCollection["oldId"] = data.oldId;
  2722.               varProvider.newAddedCollection["newId"] = data.id;
  2723.               var colLen = collectionList.length;
  2724.               for (var i = 0; i < colLen; i++) {
  2725.                 if (collectionList[i].id == data["oldId"]) {
  2726.                   collectionList[i]["id"] = data.id;
  2727.                   collectionList[i]["updatedAt"] = data.updatedAt;
  2728.                   break;
  2729.                 }
  2730.               }
  2731.             });
  2732.             this.logCollectionSaveEvent(title);
  2733.             this.setState({ addCollectionValid: false, refreshCollection: !this.state.refreshCollection });
  2734.             this.closeAddCollectionModal();
  2735.           }
  2736.         } else {
  2737.           this.setState({ addCollectionValid: true, addCollectionValidationText: translate("NC_VALIDATION") });
  2738.         }
  2739.       } else {
  2740.         this.setState({ addCollectionValid: true, addCollectionValidationText: translate("NC_EMPTY") });
  2741.       }
  2742.     }
  2743.   }
  2744.  
  2745.   logCollectionSaveEvent(name) {
  2746.     let collectionSaveJson = {
  2747.       "name": name,
  2748.       "source": "Collection"
  2749.     }
  2750.     analyticsProvider.logAnalyticsJson("CollectionSave", collectionSaveJson);
  2751.   }
  2752.  
  2753.   editTitle() {
  2754.     this.setState({ editTitleCollectionModal: true, initialValue: cloneIt.title, editTitleCollectionText: cloneIt.title, editTitleCollectionValid: false });
  2755.   }
  2756.  
  2757.   getEditTitleCollectionText(e) {
  2758.     this.setState({ editTitleCollectionText: e });
  2759.   }
  2760.  
  2761.   closeEditTitleCollectionModal() {
  2762.     this.setState({ editTitleCollectionModal: false });
  2763.   }
  2764.  
  2765.   onSaveEditTitleCollection() {
  2766.     if (!this.state.editTitleCollectionText) {
  2767.       this.setState({ editTitleCollectionValid: true, editTitleCollectionValidationText: translate("NC_EMPTY") });
  2768.     }
  2769.     else {
  2770.       var trimmedTitle = this.state.editTitleCollectionText.trim();
  2771.       if (trimmedTitle) {
  2772.         if (config.collectionRegex.test(trimmedTitle)) {
  2773.           var flagCollection = false;
  2774.           for (var i = 0; i < collectionList.length; i++) {
  2775.             if (collectionList[i].title.toLowerCase() == trimmedTitle.toLowerCase()) {
  2776.               if (collectionList[i].title == cloneIt.title) {
  2777.                 if (trimmedTitle == cloneIt.title) {
  2778.                   flagCollection = true;
  2779.                 }
  2780.               }
  2781.               else {
  2782.                 flagCollection = true;
  2783.               }
  2784.             }
  2785.           }
  2786.           if (trimmedTitle.toLowerCase() == translate("FAVORITE_ARTICLES").toLowerCase()) {
  2787.             flagCollection = true;
  2788.           }
  2789.           if (flagCollection) {
  2790.             this.setState({ editTitleCollectionValid: true, editTitleCollectionValidationText: translate("NC_EXIST") });
  2791.           } else {
  2792.             cloneIt.title = trimmedTitle;
  2793.             cloneIt.pressed = false;
  2794.  
  2795.             //update the title of collection
  2796.             for (var j = 0; j < collectionList.length; j++) {
  2797.               if (collectionList[j].id == cloneIt.id) {
  2798.                 collectionList[j].title = cloneIt.title;
  2799.                 if (collectionList[j].active === true) {
  2800.                   varProvider.selectedCollectionName = cloneIt.title;
  2801.                 }
  2802.                 collectionList[j].pressed = false;
  2803.                 break;
  2804.               }
  2805.             }
  2806.  
  2807.             //sort the collection list
  2808.             collectionList.sort(colProvider.SortByName);
  2809.  
  2810.             //move collection marked as default to front
  2811.             for (var j = 0; j < collectionList.length; j++) {
  2812.               if (collectionList[j].isDefault) {
  2813.                 let tempobj = collectionList[j];
  2814.                 collectionList.splice(j, 1);
  2815.                 collectionList.unshift(tempobj);
  2816.                 break;
  2817.               }
  2818.             }
  2819.  
  2820.             colProvider.editCollection(cloneIt).subscribe(() => {
  2821.             });
  2822.  
  2823.             isEditMode = false;
  2824.             drawerLockMode = "unlocked";
  2825.             this.setState({ editTitleCollectionValid: false, editMode: false, refreshCollection: !this.state.refreshCollection });
  2826.             this.closeEditTitleCollectionModal();
  2827.           }
  2828.         } else {
  2829.           this.setState({ editTitleCollectionValid: true, editTitleCollectionValidationText: translate("NC_VALIDATION") });
  2830.         }
  2831.       } else {
  2832.         this.setState({ editTitleCollectionValid: true, editTitleCollectionValidationText: translate("NC_EMPTY") });
  2833.       }
  2834.     }
  2835.   }
  2836.  
  2837.   deleteCollection() {
  2838.     this.setState({ deleteCollectionModal: true });
  2839.   }
  2840.  
  2841.   closeDeleteCollectionModal() {
  2842.     this.setState({ deleteCollectionModal: false });
  2843.   }
  2844.  
  2845.   onDeleteCollection() {
  2846.     var index, colIdToDelete;
  2847.     for (var i = 0; i < collectionList.length; i++) {
  2848.       if (collectionList[i].title == cloneIt.title) {
  2849.         colIdToDelete = collectionList[i].id;
  2850.         collectionList.splice(i, 1);
  2851.         index = i;
  2852.         break;
  2853.       }
  2854.     }
  2855.  
  2856.     colProvider.deleteCollection(cloneIt).subscribe(() => {
  2857.       if (varProvider.selectedCollectionId != colIdToDelete || varProvider.selectedCollectionId == varProvider.defaultCollectionId) {
  2858.         if (!varProvider.isSyncInProgress) {
  2859.           colProvider.getSyncArticles(0);
  2860.         }
  2861.       }
  2862.     });
  2863.     isEditMode = false;
  2864.     drawerLockMode = "unlocked",
  2865.       this.setState({ editMode: false });
  2866.     this.closeDeleteCollectionModal();
  2867.  
  2868.     if (varProvider.selectedCollectionId == colIdToDelete) {
  2869.       if (index == 0) {
  2870.         //select collection and load its article
  2871.         this.selectColAndLoadArticle(index);
  2872.       } else {
  2873.         //select collection i-1 and load its articles
  2874.         this.selectColAndLoadArticle(index - 1);
  2875.       }
  2876.     }
  2877.   }
  2878.  
  2879.   closeTagBottomSheet = () => {
  2880.     this.setState({ openTagModal: false });
  2881.   }
  2882.   menuItemLongPress(item) {
  2883.     if (item.isDefault && item.type != staticConfig.collectionType || !item.isDefault) {
  2884.       for (var i = 0; i < collectionList.length; i++) {
  2885.         if (collectionList[i].pressed) {
  2886.           collectionList[i].pressed = false;
  2887.         }
  2888.       }
  2889.       item.pressed = true;
  2890.       isEditMode = true;
  2891.       drawerLockMode = "locked-open",
  2892.         this.setState({ editMode: true, cloneItem: item, refreshCollection: !this.state.refreshCollection });
  2893.       cloneIt = item;
  2894.     }
  2895.   }
  2896.  
  2897.   menuItemPress(item) {
  2898.     // console.log(item)
  2899.     if (isEditMode) {
  2900.       this.closeEditMode();
  2901.     }
  2902.     else {
  2903.       this.drawer.closeDrawer();
  2904.       for (var i = 0; i < collectionList.length; i++) {
  2905.         if (collectionList[i].active) {
  2906.           collectionList[i].active = false;
  2907.         }
  2908.       }
  2909.       item.active = true;
  2910.  
  2911.       if (item.id != "favoriteArticles") {
  2912.         favoriteArticles.active = false;
  2913.         imagePath = imageJson.collection_empty;
  2914.         title = translate("ARTICLES_EMPTY1")
  2915.         text = ""
  2916.         links = [{ name: translate("ERESOURCES"), onPressFun: this.openEResources.bind(this) }, { name: translate("WEB"), onPressFun: this.openWeb.bind(this) }];
  2917.         isLink = true;
  2918.       }
  2919.       else {
  2920.         imagePath = imageJson.fav_article_empty;
  2921.         title = translate("ARTICLES_FAV_EMPTY")
  2922.         text = translate("ARTICLES_FAV_EMPTY_DATA1")
  2923.         isLink = false;
  2924.       }
  2925.  
  2926.       noMoreData = false;
  2927.       articleList = [];
  2928.       varProvider.selectedCollectionName = item.title;
  2929.       varProvider.selectedCollectionId = item.id;
  2930.       graphError = ""
  2931.       this.setState({ refreshCollection: !this.state.refreshCollection, articleLoading: true, errorLoading: false, articleLength: 0 });
  2932.  
  2933.       setTimeout(() => {
  2934.         if (item.id == "favoriteArticles") {
  2935.           if (this.state.isFilter) {
  2936.             this.callbackFun(this.state.activeFilters);
  2937.           } else {
  2938.             var tempJson = {
  2939.               "offset": 0
  2940.             };
  2941.             this.loadFavoriteArticles(tempJson);
  2942.           }
  2943.         } else {
  2944.           if (this.state.isFilter) {
  2945.             this.callbackFun(this.state.activeFilters);
  2946.           } else {
  2947.             isFirstTime = false;
  2948.             this.loadArticleList();
  2949.           }
  2950.         }
  2951.       }, 450);
  2952.     }
  2953.   }
  2954.  
  2955.   openEResources() {
  2956.     varProvider.activeTabIndex = 1;
  2957.     const { navigate } = this.props.navigation;
  2958.     navigate('Content');
  2959.   }
  2960.  
  2961.   openWeb() {
  2962.     if (connection.isConnectedFun()) {
  2963.       varProvider.openSearch = true;
  2964.       varProvider.activeTabIndex = 0;
  2965.       const { navigate } = this.props.navigation;
  2966.       navigate('Home');
  2967.     }
  2968.     else {
  2969.       Toast.showShortCenter(translate("PLEASE_CONNECT"));
  2970.     }
  2971.   }
  2972.  
  2973.   loadFavoriteArticles(tempJson) {
  2974.     if (tempJson.offset == 0)
  2975.       articleList = [];
  2976.  
  2977.     colProvider.getFavoriteArticleSql(tempJson).then((data) => {
  2978.       if (data.length < pagingCount) {
  2979.         noMoreData = true;
  2980.       }
  2981.       if (data.length != 0) {
  2982.         var articleCount = articleList.length;
  2983.         this.processArticleList(data, articleCount);
  2984.       } else {
  2985.         this.setState({ refresh: !this.state.refresh, articleLoading: false, footerLoading: false, articleLength: articleList.length });
  2986.       }
  2987.       isInfiniteOn = false;
  2988.     })
  2989.   }
  2990.  
  2991.   removeFromFavorite(item) {
  2992.     for (var i = 0; i < articleList.length; i++) {
  2993.       if (articleList[i].id == item.id) {
  2994.         articleList.splice(i, 1);
  2995.         break;
  2996.       }
  2997.     }
  2998.     this.setState({ refresh: !this.state.refresh });
  2999.   }
  3000.  
  3001.   selectColAndLoadArticle(index) {
  3002.     for (var i = 0; i < collectionList.length; i++) {
  3003.       if (collectionList[i].active) {
  3004.         collectionList[i].active = false;
  3005.       }
  3006.     }
  3007.     collectionList[index].active = true;
  3008.     graphError = ""
  3009.     this.setState({ refreshCollection: !this.state.refreshCollection, articleLoading: true, errorLoading: false, articleLength: 0 });
  3010.  
  3011.     noMoreData = false;
  3012.     articleList = [];
  3013.     varProvider.selectedCollectionName = collectionList[index].title;
  3014.     varProvider.selectedCollectionId = collectionList[index].id;
  3015.  
  3016.     if (this.state.isFilter) {
  3017.       this.callbackFun(this.state.activeFilters);
  3018.     } else {
  3019.       isFirstTime = false;
  3020.       this.loadArticleList();
  3021.     }
  3022.  
  3023.     cloneIt = collectionList[index];
  3024.   }
  3025.  
  3026.   onDrawerClose() {
  3027.     if (cloneIt) {
  3028.       cloneIt.pressed = false;
  3029.     }
  3030.     if (this.refs["searchInput"]) {
  3031.       this.refs["searchInput"].blur();
  3032.     }
  3033.     isEditMode = false;
  3034.     drawerLockMode = "unlocked";
  3035.     this.setState({ editMode: false, refreshCollection: !this.state.refreshCollection });
  3036.   }
  3037.  
  3038. }
  3039.  
  3040.