Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add download functionality #82

Merged
merged 18 commits into from
Aug 7, 2022
Merged

Conversation

mdbraber
Copy link
Contributor

@mdbraber mdbraber commented Jun 8, 2022

Initial commit for adding in-app download functionality. @joelekstrom there's a few settings that should be user-configurable (selecting download-directory and auto-opening extensions). Could you take a look at how to integrate those in the settings window? I've added a FIXME statement in places to check.

Copy link
Owner

@joelekstrom joelekstrom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Much appreciated

Fastmate/WebViewController.m Outdated Show resolved Hide resolved
Fastmate/WebViewController.m Show resolved Hide resolved
Fastmate/WebViewController.m Outdated Show resolved Hide resolved
Fastmate/WebViewController.m Outdated Show resolved Hide resolved
Fastmate/WebViewController.m Outdated Show resolved Hide resolved
@mdbraber
Copy link
Contributor Author

@joelekstrom got it to work - see changes in the PR. Can you help check and also take a look at ideas for integrating this in the settings. Or do we not need to make any of this configurable (download location, auto-open)?

@joelekstrom
Copy link
Owner

@mdbraber I think as a first step it's good enough without settings - of course a setting would be nice but that could be another PR 👍

Copy link
Owner

@joelekstrom joelekstrom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks much better, with a few notes!

Fastmate/DownloadFileManager.m Outdated Show resolved Hide resolved
Fastmate/DownloadManager.h Outdated Show resolved Hide resolved
Fastmate/DownloadManager.m Outdated Show resolved Hide resolved
Fastmate/DownloadManager.m Outdated Show resolved Hide resolved
Fastmate/DownloadManager.m Outdated Show resolved Hide resolved
Fastmate/DownloadManager.m Outdated Show resolved Hide resolved
Fastmate/FileDownloadTask.m Outdated Show resolved Hide resolved
Fastmate/FileDownloadTask.m Outdated Show resolved Hide resolved
Fastmate/FileDownloadTask.m Show resolved Hide resolved
@mdbraber
Copy link
Contributor Author

mdbraber commented Jun 13, 2022

@joelekstrom I've created a final update to include download related settings and to use a FileDownloadManager to detect already running downloaded processes. Should be the last update before we can hopefully finish this. I might have done some illogical things as I'm still rather inexperienced coding in Obj-C :-) Thanks for your feedback so far.

@mdbraber mdbraber changed the title Initial commit download functionality Add download functionality Jun 15, 2022
@joelekstrom
Copy link
Owner

joelekstrom commented Jun 15, 2022

@mdbraber Great job! I've looked through the code and will come back with some suggestions, but all in all this seems like a real nice solution to me.

But one confusion - when I'm trying this locally I can clearly see the .fmdownload file, but I can't see any progress indicator on it in finder/dock or on my downloads folder. Do you see the actual progress locally? (and with progress I mean an animated progress bar, I can see the file size increasing)

@mdbraber
Copy link
Contributor Author

mdbraber commented Jun 15, 2022

Thanks Joel. Yes I can see the download progress bar. But I've found out that with sandboxed paths the progress bar doesn't always show up reliably. A suggestion to to try out, change line 118 of FileDownloadTask.m to this:
[[NSURL fileURLWithPath:self.downloadingPath] URLByResolvingSymlinksInPath], @"NSProgressFileURLKey", - does that fix things for you?

It would be good to get some more people (including ourselves) to test it as I imagine there might be some edge cases, e.g. a stalled download where for some reason the download doesn't progress can't be fixed by removing the fmdownload file, becuase FileDownloadManager will still think it's downloading as part of the sessions variable. Maybe there should be some other / additional logic to manage the current downloads?

@joelekstrom
Copy link
Owner

Hmm, no that still doesn't help for me. I will investigate a bit more when I get the time. I also think we can use the NSURLSessionDownloadTask to slim it down a bit, still just creating a tempt file at target location. I will experiment a bit and see if I can get it to work!

@mdbraber
Copy link
Contributor Author

mdbraber commented Jun 16, 2022

I've considered using NSURLSessionDownloadTask as it would be the likely designated class for this. My consideration is that a temporary file is created in a cache location and the progress of the download (e.g. byte size of the file) can't be seen if we create an empty .fmdownload file. I opted for streaming of the output, rather than 0-byte temp file.

Btw, this is how it looks for me:
Fastmail progress

@mdbraber
Copy link
Contributor Author

mdbraber commented Jun 16, 2022

@joelekstrom here's a small POC I've created to test the progress indicator:

#import <Foundation/Foundation.h>

// clang progress.mm -framework Cocoa -o progress
// ./progress

int main (int argc, const char * argv[])
{    
    NSDictionary* userInfo = @{
        NSProgressFileOperationKindKey : NSProgressFileOperationKindReceiving,
        NSProgressFileURLKey : [NSURL fileURLWithPath:@"/Users/mdbraber/Downloads/Test.pdf"],
    };

    NSProgress *progress = [[NSProgress alloc] initWithParent:nil userInfo:userInfo];    
    progress.kind = NSProgressKindFile;
    progress.pausable = NO;
    progress.cancellable = YES;
    progress.totalUnitCount = 10;

    [progress publish];

    for (NSUInteger completedUnits = 0; completedUnits < progress.totalUnitCount; ++completedUnits) {
        if ([progress isCancelled]) {
            NSLog(@"Cancelled!");
            break;
        }

        sleep(1);
        
        NSLog(@"Progress...");
        [progress setCompletedUnitCount:(completedUnits + 1)];
    }

    return 0;
}

@joelekstrom
Copy link
Owner

Interesting that I don't see it, must be something with my setup 🤔 will try a bit more. You can get progress from URLSessionDownloadTask using URLSessionDownloadDelegate: https://developer.apple.com/documentation/foundation/urlsessiondownloaddelegate/1409408-urlsession

I was thinking there's still a tmp .fmdownload file created where we post the progress, but then you don't need to handle the download buffering etc

@mdbraber
Copy link
Contributor Author

mdbraber commented Jun 16, 2022

Sorry @joelekstrom I accidentally posted the wrong POC - I've edited the comment above with the right POC and instructions (copied from https://gist.github.com/torarnv/0a4b6b4509bad7682b2dc0c561ec4437). Wondering if this POC would work for you. Main things I found that prevent the progress bar from showing are (1) fileURL paths with symlinked locations (2) forgetting to use publish

Regarding NSURLSessionDownloadTask I agree it means not having to handle download buffering, but the file size wouldn't be reflected in the Finder. I've taken a cue from Safari to see how they do it, and there the file is streamed directly to a download location (actually it's a bit different, the Safari .download file is actually a package file which holds the temporary file) Of course I think it's fine if you would prefer to switch to NSURLSessionDownloadTask but I think personally I prefer this approach.

@joelekstrom
Copy link
Owner

All right, sounds good let's keep this approach! 👍 I'll try to test the POC if I get some time layer today

@joelekstrom
Copy link
Owner

Interestingly, I do see the progress bar when running the POC, but not in Fastmate. Gonna have to try a bit more 🤔

@joelekstrom
Copy link
Owner

So strange, I got it to work once in Fastmate but then it stopped. I think something is acting up. Will debug a bit more tomorrow.

Btw, you can set up the progress object a bit more nicely this way:

    self.progress = [NSProgress progressWithTotalUnitCount:_totalBytes];
    self.progress.fileOperationKind = NSProgressFileOperationKindDownloading;
    self.progress.fileURL = [[NSURL fileURLWithPath:self.downloadingPath] URLByResolvingSymlinksInPath];
    self.progress.kind = NSProgressKindFile;
    self.progress.pausable = NO;
    self.progress.cancellable = YES;

@mdbraber
Copy link
Contributor Author

Thanks for the update @joelekstrom, update the initialization. Any update on getting the progress bar to work on your side?

@joelekstrom
Copy link
Owner

Been a bit busy lately so haven't spent much time on it! However, if we can't get this to work perfectly that's fine. We could also ship it as a preference disabled by default to allow people to beta test it. Let people opt in to this new download experience and see how it goes. It might just be my computer acting up 😄

@mdbraber
Copy link
Contributor Author

We could make the whole download functionality optional, I would than suggest switching it on by default qn making it possible to revert to the current behavior

@joelekstrom
Copy link
Owner

Yep, that sounds good to me! Would you like to add a preference for it? (Sorry for being so slow btw)

@mdbraber
Copy link
Contributor Author

@joelekstrom yes, I'll add a preference for the download behavior in general, so people can toggle it on/off. No problem about the response time, I can relate :-) Would be nice to ship a version in the coming days / weeks, especially to get some feedback from people what can be improved.

@joelekstrom
Copy link
Owner

I agree! Would also be nice to ship the other patches you’ve made

Revised download logic using NSOutputStream
Added progress indicator for downloads
Added temporary download file format (.fmdownload)
@joelekstrom
Copy link
Owner

Hi @mdbraber! I feel like it's time we get this out. I rebased the branch added some minor changes including a setting to fall back to legacy downloads. Any thoughts on those? Otherwise I'll merge it and ship a new update soon. Thanks again for all the work on this!

@joelekstrom joelekstrom merged commit 5a63a1f into joelekstrom:master Aug 7, 2022
joelekstrom added a commit that referenced this pull request Aug 8, 2022
* In-app download support #82
Fastmate now downloads directly to a folder (which can be changed in settings) instead of opening an external browser. The old behavior can still be enabled in settings.
* Add basic AppleScript support #81
* Add support for opening Fastmail https:// links #88
* Fix some shortcuts not working with new Fastmail layout #70

Big thanks to @mdbraber for all the work on these new features!
@mdbraber
Copy link
Contributor Author

@joelekstrom sorry for the delayed reply I was away for a bit. Thanks for merging this and adding a setting to revert to the legacy behavior. I think only one small detail to check now with users is if we can get the progress bar to show. It still shows on my install, but I've heard from at least one other user it (also, like with you) doesn't show up. Any ideas how we could get some user feedback on that?

@joelekstrom
Copy link
Owner

@mdbraber no problem! It does show on my new computer so it may have been something with my setup on the previous one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants