public async Task <List <CachedDriveItem> > GetCachedChildrenFromDrive(string SelectedDriveId, string ItemId)
        {
            List <CachedDriveItem> itemsToReturn = null;

            // Search for CachedDriveItems in the CachedDrive with the specified DriveId and ItemId
            try
            {
                CachedDrive DriveToSearch = null;
                IEnumerable <CachedDriveItem> ChildrenFromDrive = null;
                lock (CacheLock)
                {
                    DriveToSearch = CurrentUserCache.Drives.First(drive => drive.DriveId.Equals(SelectedDriveId) && drive.Id.Equals(ItemId));
                    // Get all items with a ParentItemId equal to the 2nd argument ItemId, so the direct children of a drive
                    ChildrenFromDrive = DriveToSearch.ItemList.Where(item => item.ParentItemId.Equals(ItemId));
                }
                bool HasNoChildrenCache = false;
                lock (CacheLock)
                {
                    HasNoChildrenCache = !ChildrenFromDrive.Any();
                }
                if (HasNoChildrenCache)
                {
                    // Found no children from the specified drive in cache, so we need to fetch the latest from Graph
                    itemsToReturn = await GetDriveChildrenFromGraph(SelectedDriveId, ItemId);

                    lock (CacheLock)
                    {
                        // Since there are no items with a ParentItemId set to the drive, there cannot be any other items,
                        // since they would be eventually be children of items which are children of the drive
                        DriveToSearch.ItemList = itemsToReturn;
                    }
                }
                else
                {
                    lock (CacheLock)
                    {
                        itemsToReturn = ChildrenFromDrive.ToList();
                    }
                }
                // We need to update the cache here on another thread without potentially destroying other saved items,
                // so we can't just overwrite the ItemList
                new Thread(async() =>
                {
                    await UpdateDriveChildrenCache(SelectedDriveId, ItemId);
                }).Start();
                return(itemsToReturn);
            }
            catch (InvalidOperationException)
            {
                // If there is no Drive witht the specified driveId, an InvalidOperationException will be thrown.
                // This means the user clicked on a drive in cache (but this cache was updated at startup)
                return(null);
            }
        }
 public bool IsParentChildOfDrive(CachedDrive SelectedDriveFolder, string ParentId)
 {
     lock (CacheLock)
     {
         try
         {
             CachedDrive CurrentDrive = CurrentUserCache.Drives.First((currentDrive) => SelectedDriveFolder.DriveId.Equals(currentDrive.DriveId) && SelectedDriveFolder.Id.Equals(ParentId));
             return(true);
         }
         catch (InvalidOperationException)
         {
             return(false);
         }
     }
 }
        public async Task <List <CachedDrive> > GetDrivesFromGraph()
        {
            // Compile a list of drives, straight from Graph
            List <DriveItem> localDriveList = new List <DriveItem>();

            localDriveList.Add(await Graph.GetUserRootDrive());

            IDriveSharedWithMeCollectionPage sharedDrivesCollection = await Graph.GetSharedDrivesAsync();

            foreach (DriveItem drive in sharedDrivesCollection)
            {
                if (drive.Folder != null)
                {
                    localDriveList.Add(drive);
                }
            }

            // Convert the Graph format
            List <CachedDrive> newlyCachedDrives = new List <CachedDrive>();

            foreach (DriveItem graphDrive in localDriveList)
            {
                CachedDrive driveToAdd = new CachedDrive
                {
                    Id            = graphDrive.Id,
                    ChildrenCount = graphDrive.Folder.ChildCount
                };
                // Check if the current graphDrive in the localDriveList is the personal graphDrive
                if (graphDrive.RemoteItem is null)
                {
                    // this is the personal drive
                    driveToAdd.DriveName      = "Your Drive";
                    driveToAdd.DriveId        = graphDrive.ParentReference.DriveId;
                    driveToAdd.IsSharedFolder = false;
                }
                else
                {
                    driveToAdd.DriveName      = graphDrive.Name;
                    driveToAdd.DriveId        = graphDrive.RemoteItem.ParentReference.DriveId;
                    driveToAdd.IsSharedFolder = true;
                }
                newlyCachedDrives.Add(driveToAdd);
            }
            return(newlyCachedDrives);
        }
 public CachedDriveItem GetParentItemByParentItemId(CachedDrive SelectedDriveFolder, string ParentId)
 {
     lock (CacheLock)
     {
         try
         {
             // Get the current drive from the cache
             CachedDrive     CurrentDrive = CurrentUserCache.Drives.First((currentDrive) => currentDrive.DriveId.Equals(SelectedDriveFolder.DriveId) && currentDrive.Id.Equals(SelectedDriveFolder.Id));
             CachedDriveItem Parent       = CurrentDrive.ItemList.First((currentItem) => currentItem.ItemId.Equals(ParentId));
             return(Parent);
         }
         catch (InvalidOperationException)
         {
             // This should not happen.
             return(null);
         }
     }
 }
        public async Task <List <CachedDriveItem> > GetCachedChildrenFromItem(CachedDrive SelectedDrive, string ItemId)
        {
            List <CachedDriveItem> CurrentlyCachedItems = null;
            List <CachedDriveItem> ChildrenFromItem     = null;

            lock (CacheLock)
            {
                CurrentlyCachedItems = CurrentUserCache.Drives.First((currentItem) =>
                                                                     currentItem.DriveId.Equals(SelectedDrive.DriveId) && currentItem.Id.Equals(SelectedDrive.Id)
                                                                     ).ItemList;

                ChildrenFromItem = new List <CachedDriveItem>();

                // There are children, so we need to search the ItemList for them by comparing the ParentItemId and ItemId
                CurrentlyCachedItems.ForEach((currentItem) =>
                {
                    if (currentItem.ParentItemId.Equals(ItemId))
                    {
                        ChildrenFromItem.Add(currentItem);
                    }
                });
            }

            if (ChildrenFromItem.Count == 0)
            {
                // There were no items with the correct ParentItemId, so we need to call Graph
                ChildrenFromItem = await GetItemChildrenFromGraph(SelectedDrive.DriveId, ItemId);

                // check for non-existant folder
                if (ChildrenFromItem is null)
                {
                    ChildrenFromItem = new List <CachedDriveItem>();
                }
            }
            // Now update the cache on another thread.
            new Thread(async() =>
            {
                await UpdateItemChildrenCache(SelectedDrive.DriveId, SelectedDrive.Id, ItemId);
            }).Start();
            return(ChildrenFromItem);
        }
 public List <CachedDriveItem> GetDriveOrItemsWithParentId(CachedDrive SelectedDriveFolder, string ParentId)
 {
     // We need to get the parent of the current ParentItem. If we have that parent, we can get it's children.
     // That parent is either a CachedDrive or a CachedDriveItem
     lock (CacheLock)
     {
         try
         {
             // check to see if the SelectedDriveFolder is the parent of the current ParentItem
             CachedDrive            CurrentDrive = CurrentUserCache.Drives.First((currentDrive) => SelectedDriveFolder.DriveId.Equals(currentDrive.DriveId) && SelectedDriveFolder.Id.Equals(currentDrive.Id));
             List <CachedDriveItem> ParentItems  = new List <CachedDriveItem>();
             //if (CurrentDrive.Id.Equals(ParentId))
             //{
             CurrentDrive.ItemList.ForEach((currentItem) =>
             {
                 if (currentItem.ParentItemId.Equals(ParentId))
                 {
                     ParentItems.Add(currentItem);
                 }
             });
             //}
             //else
             //{
             //The parent of the current ParentItem is not a CachedDrive, so it must be a CachedDriveItem
             //	CurrentDrive.ItemList.ForEach((currentItem) =>
             //	{
             //		if (currentItem.ItemId.Equals(ParentId))
             //		{
             //			ParentItems.Add(currentItem);
             //		}
             //	});
             //}
             return(ParentItems);
         }
         catch (InvalidOperationException)
         {
             return(null);
         }
     }
 }