Skip to content

Commit

Permalink
Merge pull request #1672 from ardriveapp/PE-5845-improve-sync-and-dri…
Browse files Browse the repository at this point in the history
…ve-explorer-navigation-performance-by-removing-the-usage-of-paths-on-folders-and-files

PE-5845: improve sync and drive explorer navigation performance by removing the usage of paths on folders and files
  • Loading branch information
thiagocarvalhodev authored Apr 16, 2024
2 parents 46a36e1 + 9825f45 commit 361bf51
Show file tree
Hide file tree
Showing 54 changed files with 941 additions and 697 deletions.
5 changes: 3 additions & 2 deletions lib/authentication/ardrive_auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,9 @@ class ArDriveAuthImpl implements ArDriveAuth {

final privateDrive = await _arweave.getLatestDriveEntityWithId(
firstDrivePrivateDriveTxId,
checkDriveKey,
profileQueryMaxRetries,
driveKey: checkDriveKey,
driveOwner: await wallet.getAddress(),
maxRetries: profileQueryMaxRetries,
);

return privateDrive != null;
Expand Down
21 changes: 16 additions & 5 deletions lib/blocs/create_manifest/create_manifest_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:async';

import 'package:ardrive/blocs/blocs.dart';
import 'package:ardrive/core/arfs/repository/file_repository.dart';
import 'package:ardrive/core/arfs/repository/folder_repository.dart';
import 'package:ardrive/entities/entities.dart';
import 'package:ardrive/entities/manifest_data.dart';
import 'package:ardrive/models/models.dart';
Expand Down Expand Up @@ -31,6 +33,10 @@ class CreateManifestCubit extends Cubit<CreateManifestState> {
final TurboUploadService _turboUploadService;
final DriveDao _driveDao;
final PstService _pst;

final FolderRepository _folderRepository;
final FileRepository _fileRepository;

bool _hasPendingFiles = false;

StreamSubscription? _selectedFolderSubscription;
Expand All @@ -43,12 +49,16 @@ class CreateManifestCubit extends Cubit<CreateManifestState> {
required DriveDao driveDao,
required PstService pst,
required bool hasPendingFiles,
required FileRepository fileRepository,
required FolderRepository folderRepository,
}) : _profileCubit = profileCubit,
_arweave = arweave,
_turboUploadService = turboUploadService,
_driveDao = driveDao,
_pst = pst,
_hasPendingFiles = hasPendingFiles,
_fileRepository = fileRepository,
_folderRepository = folderRepository,
super(CreateManifestInitial()) {
if (drive.isPrivate) {
// Extra guardrail to prevent private drives from creating manifests
Expand Down Expand Up @@ -215,10 +225,14 @@ class CreateManifestCubit extends Cubit<CreateManifestState> {
try {
final parentFolder =
(state as CreateManifestPreparingManifest).parentFolder;

final folderNode = rootFolderNode.searchForFolder(parentFolder.id) ??
await _driveDao.getFolderTree(drive.id, parentFolder.id);
final arweaveManifest = ManifestData.fromFolderNode(

final arweaveManifest = await ManifestData.fromFolderNode(
folderNode: folderNode,
fileRepository: _fileRepository,
folderRepository: _folderRepository,
);

final profile = _profileCubit.state as ProfileLoggedIn;
Expand Down Expand Up @@ -253,10 +267,7 @@ class CreateManifestCubit extends Cubit<CreateManifestState> {

addManifestToDatabase() => _driveDao.transaction(
() async {
await _driveDao.writeFileEntity(
manifestFileEntity,
'${parentFolder.path}/$manifestName',
);
await _driveDao.writeFileEntity(manifestFileEntity);
await _driveDao.insertFileRevision(
manifestFileEntity.toRevisionCompanion(
performedAction: existingManifestFileId == null
Expand Down
8 changes: 5 additions & 3 deletions lib/blocs/drive_attach/drive_attach_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class DriveAttachCubit extends Cubit<DriveAttachState> {

final driveEntity = await _arweave.getLatestDriveEntityWithId(
driveId,
_driveKey,
driveKey: _driveKey,
);

if (driveEntity == null) {
Expand Down Expand Up @@ -188,7 +188,8 @@ class DriveAttachCubit extends Cubit<DriveAttachState> {
}
}

final drive = await _arweave.getLatestDriveEntityWithId(driveId, _driveKey);
final drive =
await _arweave.getLatestDriveEntityWithId(driveId, driveKey: _driveKey);

if (drive == null) {
return false;
Expand All @@ -208,7 +209,8 @@ class DriveAttachCubit extends Cubit<DriveAttachState> {

_driveKey = await getDriveKey(promptedDriveKey);

final drive = await _arweave.getLatestDriveEntityWithId(driveId, _driveKey);
final drive =
await _arweave.getLatestDriveEntityWithId(driveId, driveKey: _driveKey);

if (drive == null) {
return 'Invalid drive key';
Expand Down
51 changes: 36 additions & 15 deletions lib/blocs/drive_detail/drive_detail_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'dart:async';

import 'package:ardrive/authentication/ardrive_auth.dart';
import 'package:ardrive/blocs/blocs.dart';
import 'package:ardrive/blocs/drive_detail/utils/breadcrumb_builder.dart';
import 'package:ardrive/core/activity_tracker.dart';
import 'package:ardrive/entities/constants.dart';
import 'package:ardrive/models/models.dart';
import 'package:ardrive/pages/pages.dart';
import 'package:ardrive/services/services.dart';
Expand All @@ -29,6 +29,7 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
final ConfigService _configService;
final ArDriveAuth _auth;
final ActivityTracker _activityTracker;
final BreadcrumbBuilder _breadcrumbBuilder;

StreamSubscription? _folderSubscription;
final _defaultAvailableRowsPerPage = [25, 50, 75, 100];
Expand All @@ -52,11 +53,13 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
required ConfigService configService,
required ActivityTracker activityTracker,
required ArDriveAuth auth,
required BreadcrumbBuilder breadcrumbBuilder,
}) : _profileCubit = profileCubit,
_activityTracker = activityTracker,
_driveDao = driveDao,
_auth = auth,
_configService = configService,
_breadcrumbBuilder = breadcrumbBuilder,
super(DriveDetailLoadInProgress()) {
if (driveId.isEmpty) {
return;
Expand All @@ -70,11 +73,15 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
.getSingleOrNull();
// Open the root folder if the deep-linked folder could not be found.

openFolder(path: folder?.path ?? rootPath);
openFolder(folderId: folder?.id);
// The empty string here is required to open the root folder
});
} else {
openFolder(path: rootPath);
Future.microtask(() async {
final drive =
await _driveDao.driveById(driveId: driveId).getSingleOrNull();
openFolder(folderId: drive?.rootFolderId);
});
}
}

Expand All @@ -85,7 +92,7 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
}

void openFolder({
required String path,
String? folderId,
DriveOrder contentOrderBy = DriveOrder.name,
OrderingMode contentOrderingMode = OrderingMode.asc,
}) async {
Expand All @@ -111,9 +118,15 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
}

try {
await _driveDao.getFolderTree(driveId, value.rootFolderId);
await _driveDao
.folderById(
driveId: driveId,
folderId: folderId ?? value.rootFolderId,
)
.getSingle();
} catch (e) {
logger.d('Folder with id ${value.rootFolderId} not found');
logger
.d('Folder with id ${folderId ?? value.rootFolderId} not found');

emit(DriveInitialLoading());
return;
Expand All @@ -125,9 +138,9 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
_driveDao.driveById(driveId: driveId).watchSingle(),
_driveDao.watchFolderContents(
driveId,
folderPath: path,
orderBy: contentOrderBy,
orderingMode: contentOrderingMode,
folderId: folderId,
),
_profileCubit.stream.startWith(ProfileCheckingAvailability()),
(drive, folderContents, _) async {
Expand All @@ -141,15 +154,10 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {

final profile = _profileCubit.state;

var availableRowsPerPage = _defaultAvailableRowsPerPage;

availableRowsPerPage = calculateRowsPerPage(
final availableRowsPerPage = calculateRowsPerPage(
folderContents.files.length + folderContents.subfolders.length,
);

final rootFolderNode =
await _driveDao.getFolderTree(driveId, drive.rootFolderId);

if (_selectedItem != null && _refreshSelectedItem) {
if (_selectedItem is FileDataTableItem) {
final index = folderContents.files.indexWhere(
Expand Down Expand Up @@ -193,6 +201,13 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
isOwner: isDriveOwner(_auth, drive.ownerAddress),
);

final List<BreadCrumbRowInfo> pathSegments =
await _breadcrumbBuilder.buildForFolder(
folderId: folderContents.folder.id,
rootFolderId: drive.rootFolderId,
driveId: driveId,
);

if (state != null) {
emit(
state.copyWith(
Expand All @@ -207,12 +222,17 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
availableRowsPerPage: availableRowsPerPage,
currentFolderContents: currentFolderContents,
isShowingHiddenFiles: _showHiddenFiles,
pathSegments: pathSegments,
driveIsEmpty: folderContents.files.isEmpty &&
folderContents.subfolders.isEmpty,
),
);
} else {
final columnsVisibility = await getTableColumnVisibility();

emit(
DriveDetailLoadSuccess(
pathSegments: pathSegments,
selectedItem: _selectedItem,
currentDrive: drive,
hasWritePermissions: profile is ProfileLoggedIn &&
Expand All @@ -222,7 +242,8 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
contentOrderingMode: contentOrderingMode,
rowsPerPage: availableRowsPerPage.first,
availableRowsPerPage: availableRowsPerPage,
driveIsEmpty: rootFolderNode.isEmpty(),
driveIsEmpty: folderContents.files.isEmpty &&
folderContents.subfolders.isEmpty,
multiselect: false,
currentFolderContents: currentFolderContents,
columnVisibility: columnsVisibility,
Expand Down Expand Up @@ -393,7 +414,7 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
}) {
final state = this.state as DriveDetailLoadSuccess;
openFolder(
path: state.folderInView.folder.path,
folderId: state.folderInView.folder.id,
contentOrderBy: contentOrderBy,
contentOrderingMode: contentOrderingMode,
);
Expand Down
5 changes: 5 additions & 0 deletions lib/blocs/drive_detail/drive_detail_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class DriveDetailLoadSuccess extends DriveDetailState {

final FolderWithContents folderInView;

final List<BreadCrumbRowInfo> pathSegments;

final DriveOrder contentOrderBy;
final OrderingMode contentOrderingMode;

Expand Down Expand Up @@ -59,6 +61,7 @@ class DriveDetailLoadSuccess extends DriveDetailState {
required this.columnVisibility,
this.forceRebuildKey,
required this.isShowingHiddenFiles,
required this.pathSegments,
});

DriveDetailLoadSuccess copyWith({
Expand All @@ -79,6 +82,7 @@ class DriveDetailLoadSuccess extends DriveDetailState {
List<ArDriveDataTableItem>? currentFolderContents,
Key? forceRebuildKey,
bool? isShowingHiddenFiles,
List<BreadCrumbRowInfo>? pathSegments,
}) =>
DriveDetailLoadSuccess(
columnVisibility: columnVisibility,
Expand All @@ -102,6 +106,7 @@ class DriveDetailLoadSuccess extends DriveDetailState {
currentFolderContents:
currentFolderContents ?? this.currentFolderContents,
isShowingHiddenFiles: isShowingHiddenFiles ?? this.isShowingHiddenFiles,
pathSegments: pathSegments ?? this.pathSegments,
);

@override
Expand Down
39 changes: 39 additions & 0 deletions lib/blocs/drive_detail/utils/breadcrumb_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'package:ardrive/core/arfs/repository/folder_repository.dart';
import 'package:ardrive/pages/drive_detail/drive_detail_page.dart';
import 'package:ardrive/utils/logger.dart';

class BreadcrumbBuilder {
final FolderRepository _folderRepository;

BreadcrumbBuilder(this._folderRepository);

Future<List<BreadCrumbRowInfo>> buildForFolder({
required String folderId,
required String rootFolderId,
required String driveId,
}) async {
List<BreadCrumbRowInfo> breadcrumbs = [];
String? currentFolderId = folderId;

while (currentFolderId != null && currentFolderId != rootFolderId) {
final folderRevision = await _folderRepository
.getLatestFolderRevisionInfo(driveId, currentFolderId);
if (folderRevision == null) {
logger.e('FolderRevision not found for folderId: $currentFolderId');
throw Exception(
'FolderRevision not found for folderId: $currentFolderId');
}

breadcrumbs.insert(
0,
BreadCrumbRowInfo(
text: folderRevision.name,
targetId: folderRevision.folderId,
),
);
currentFolderId = folderRevision.parentFolderId;
}

return breadcrumbs;
}
}
1 change: 0 additions & 1 deletion lib/blocs/folder_create/folder_create_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ class FolderCreateCubit extends Cubit<FolderCreateState> {
driveId: targetFolder.driveId,
parentFolderId: targetFolder.id,
folderName: folderName,
path: '${targetFolder.path}/$folderName',
);

final folderEntity = FolderEntity(
Expand Down
9 changes: 1 addition & 8 deletions lib/blocs/fs_entry_move/fs_entry_move_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class FsEntryMoveBloc extends Bloc<FsEntryMoveEvent, FsEntryMoveState> {
final TurboUploadService _turboUploadService;
final DriveDao _driveDao;
final ProfileCubit _profileCubit;
final SyncCubit _syncCubit;
final ArDriveCrypto _crypto;
final DriveDetailCubit _driveDetailCubit;

Expand All @@ -48,7 +47,6 @@ class FsEntryMoveBloc extends Bloc<FsEntryMoveEvent, FsEntryMoveState> {
_driveDao = driveDao,
_profileCubit = profileCubit,
_driveDetailCubit = driveDetailCubit,
_syncCubit = syncCubit,
_crypto = crypto,
super(const FsEntryMoveLoadInProgress()) {
if (_selectedItems.isEmpty) {
Expand Down Expand Up @@ -223,9 +221,7 @@ class FsEntryMoveBloc extends Bloc<FsEntryMoveEvent, FsEntryMoveState> {
.fileById(driveId: driveId, fileId: fileToMove.id)
.getSingle();
file = file.copyWith(
parentFolderId: parentFolder.id,
path: '${parentFolder.path}/${file.name}',
lastUpdated: DateTime.now());
parentFolderId: parentFolder.id, lastUpdated: DateTime.now());
final fileKey = driveKey != null
? await _crypto.deriveFileKey(driveKey, file.id)
: null;
Expand Down Expand Up @@ -254,7 +250,6 @@ class FsEntryMoveBloc extends Bloc<FsEntryMoveEvent, FsEntryMoveState> {
.getSingle();
folder = folder.copyWith(
parentFolderId: Value(parentFolder.id),
path: '${parentFolder.path}/${folder.name}',
lastUpdated: DateTime.now(),
);

Expand Down Expand Up @@ -296,7 +291,5 @@ class FsEntryMoveBloc extends Bloc<FsEntryMoveEvent, FsEntryMoveState> {
);
await _arweave.postTx(moveTx);
}

await _syncCubit.generateFsEntryPaths(driveId, folderMap, {});
}
}
Loading

0 comments on commit 361bf51

Please sign in to comment.