Code Monkey home page Code Monkey logo

Comments (45)

jaredlt avatar jaredlt commented on May 20, 2024 1
2016-02-15 10:20:30 UTC

Gotcha! I think when you store the String of the Time object it should it include this automatically but I will confirm.

About the link to go to the title page, your mockup looks awesome! You're a great UX designer :D

Thank you! :)

Will proceed with all as discussed 👍

from mango.

hkalexling avatar hkalexling commented on May 20, 2024 1

Sorry, I forgot to comment on the time zone issue. Yes, it looks good. No need to add UTC explicitly. I think we can assume only power users would look into the info.json file, and they should know what the Z means :)

from mango.

hkalexling avatar hkalexling commented on May 20, 2024 1

👍 I like the idea! I will fork the branch and try to create a helper function that returns the ctime of a file.

from mango.

hkalexling avatar hkalexling commented on May 20, 2024 1

Yes, please fork from the dev branch in the future. The master branch contains the source code for the latest stable release, and the dev branch contains the new features/bug fixes to be released in the next version. You can see the development guideline for more details.

Don't worry! I will handle the conflicts because I am more familiar with the new features :) You can work on the slider or update UI in a new branch.

Sorry I haven't seen the error message before. You mentioned that you are developing in WSL so I guess it's a WSL problem/misconfiguration. I googled around, and these issues (microsoft/WSL#4340 microsoft/WSL#4769) seem related. Hope that helps!

from mango.

jaredlt avatar jaredlt commented on May 20, 2024 1

Fixed it! Something got stuck in an infinite loop (I think) and there was still a version of Crystal running even though my terminal made it look like it exited. Once I fully closed the terminal and restarted it was working again :/ (on/off really is good advice!)

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

This looks amazing! Thanks for taking the time to write this :D

I am a heavy user of Plex as well, and I agree we need a more refined home page. If you want, I can invite you as a collaborator and create a branch, so we can both work on it and experiment with it.

Regarding the details:

  • I like the idea of adding the home tab and moving the original home to /library.
  • Perhaps the On Deck section can be renamed to Up Next?
  • I agree we should make the title text smaller. In the current version many long titles are truncated and it doesn't look good.
  • A Plex theme sounds interesting. Feel free to experiment with it!
  • Perhaps we can allow the users to toggle between percentage, read page and progress bar for entries? I agree showing percentage makes more sense for titles.

You proposed a few different new features (all inspired by Plex)

  1. The new home tab with the "Continue Watching" and "On Deck (Up Next)" sections
  2. Plex theme
  3. New progress indicators (read page count and progress bar)

Maybe we should pick one and work on it first? I would vote for 1, but let me know what you think!

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

@hkalexling sounds great!

Agreed, let's focus on 1. I like Up Next too 👍

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

@hkalexling I started documenting the below requirements but now I'm wondering if we need both Continue Reading AND On Deck/Up Next.

Plex's logic displays in progress episodes in On Deck/Up Next too. I guess this may be a reason why Plex named it On Deck instead of Up Next. It represents all the shows you've started watching, including any episodes in progress. I think that makes sense. Continue watching is important for Plex because you can have multiple libraries eg. 1) TV 2) Movies. Movies will never be On Deck so it makes sense to highlight them in Continue Watching, and it would be confusing if this didn't also display TV Shows that are in progress too. If you go into the TV library dashboard of Plex it shows On Deck at the top (it has continue watching much further down and this displays all episodes that are in progress, even if from the same series).

If we just have a single library, could we have a single section called Continue Reading but it actually works like Plex's On Deck? It would show the next entry (or current entry if in progress). I'm leaning towards just one section now but let me know what you think.


I'll leave my original requirements below as is for your feedback. Either way we'll need to implement the On Deck functionality and after that it will be easy if we decide want to add the Continue Watching section too.

Continue Watching/Reading

  • Display all entries which are 'in progress'

Scenarios

  • 0 entries in progress: section should not appear, including not showing the heading
  • 1 entry in progress: show entry
  • 1 entry for Title A and 1 entry for Title B: show both entries
  • 2 entries for Title A: Just show latest entry eg. vol. 2 30% and vol. 4 30% - just show vol. 4 (this follows Plex's logic which I think I agree with. Logically if you are reading a title, you read one entry at a time, in order. Therefore, if you have 2 entries for the same title 'in progress', it implies that you have read up to whatever the latest entry is. The earlier entry may be you just going back and re-reading something). This rule can be generalised to: Only show 1 'in progress' entry per title in Continue Reading and only show the latest entry.
  • ORDER BY: 1 entry for Title A last read today and 1 entry for Title B last read yesterday: show Title A entry first, then Title B entry (NB. I believe this will require adding a new section into info.json unless this is stored somewhere I'm unaware of?) Eg.
{
  "comment": "Generated by Mango. DO NOT EDIT!",
  "progress": {
    "admin": {
      "Ghost in the Shell v1 (1995) (Uncensored)": 186,
      "Ghost in the Shell v2 (2010) (Digital) (danke-Empire)": 0
    }
  },
  "last_read": { // new section (need to consider methods to refactor eg. save_progress)
    "admin": {
      "Ghost in the Shell v1 (1995) (Uncensored)": "2020-05-18 12:12:36",
    }
  },
  //...
}

NB. In the future it may be worth exploring consolidating all of the info.json data in the database. This would allow you to add a user_entries table to avoid duplicating usernames in the json. It would also avoid modifying the user's library folder, which some users may not like, and could make some of these new features easier to deal with, especially for large libraries. This would change the source of truth from the file system to the db and there is much more to think about here. Out of scope for this feature :)

On Deck/Up Next

  • Display the next entry to be read for each title you have started reading

Definitions

  • title started - has at least 1 entry either in progress or completed
  • entry started - is either in progress or completed

Scenarios

  • 0 titles started: section should not appear, including not showing the heading
  • 1 title started with 1.zip completed and no other entries (ie. title 100%): section should not appear, including not showing the heading
  • 1 title started with 1.zip in progress and no other entries: show 1.zip (Plex's logic which shows in progress in Up Next too. Probably why they named it On Deck instead of Up Next)
  • 1 title started with 1.zip in progress and 2.zip unread: show 1.zip (show current and not next entry if current is in progress)
  • 1 title started with 1.zip completed and 2.zip unread: show 2.zip
  • 1 title started with 1.zip completed and 2.zip in progress: show 2.zip
  • 1 title started with 1.zip completed and 2.zip completed: section should not appear, including not showing the heading
  • 1 title started with 1.zip completed and 2.zip completed and 3.zip unread: show 3.zip
  • 1 title started with 1.zip completed and 2.zip in progress and 3.zip unread and 4 in progress: show 4.zip
  • 1 title started with 1.zip completed and 2.zip unread and 3.zip completed: show 2.zip
  • 1 title started with 1.zip completed and 2.zip in progress and 3.zip completed: show 2.zip
  • ORDER BY: last read

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

I agree that the two sections can be merged. I think we need multi-library support later (see #13 ), but for now, merging the two makes more sense.

I try to avoid saving things to DB (unless absolutely necessary) due to the following reasons:

  1. If we store the title and entry information (progress, display names, cover images, etc.) in DB, for example, how can we refer to a certain title in DB? The only way I can think of is to use the title's path (e.g., library/manga_A ). However, if the title folder is moved or renamed, we won't be able to update the path in DB and the information will be lost. This won't be a problem with the current info.json setup, as the title folder still contains the same JSON file after moving/renaming.
  2. Mango is still in early development, and we might need to modify the DB scheme a lot if we are storing everything in DB. A simple JSON file is much more flexible.

It's a good point that users might not want the library folder to be modified. We need to plan carefully.

The rules you listed for displaying the sections are well-thought-out. I think we can go with that. Thanks for your efforts!

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

@hkalexling Proceeding with a single merged section for now 👍

RE: db vs file system - what you say makes perfect sense. And as you say, still in early development. Plex seem to handle moved files really well, by showing in the UI if they're missing and then knowing when they've come back, even if it's not the same file, but provided the naming and file structure is sufficient. I'll maybe have a poke around the Plex database to see if I can understand more how they do it, but yes, that is for much later on :)

I've pushed a new WIP branch up: feature/home. It includes:

  • Moved current index to /library, renamed relevant files / routes and added new link to nav
  • Created new view home and added new route
  • Created new method for Title class get_on_deck_entry(username) - this works and returns an array of Entries but it's not very elegant code :/
  • Fixed a typo on 2 of your existing methods load_percetage >> load_percentage

Comments

  • I'm sure the new method I've introduced, and even the code in the / route, could be cleaner / simpler / more idiomatic. Would love some feedback from you here.
  • Because the main object is an array of Entries, I'm unsure what the best approach is to get the percentage. I tried using as much existing code as possible and calling e.book.load_percentage(username, e) but this always returned 0.0 and also didn't feel very elegant. I found myself wanting to reach for a percentage method within an Entry object eg. in the view (or route) you would be able to just call e.percentage(username). Could I add this method into the Entry class? Didn't feel very DRY to do this though.
  • I wonder if we can think about making the username attribute implicit? By this I mean: we know when calling load_progress that it will always be in connection to the logged in user, so it would be good if we could just call e.load_progress in the view without having to pass in the username variable. This isn't super important right now, just thinking out loud. Perhaps we need a separate UserEntry class or something? Maybe this is one of those things that we just ignore for now and revisit if/when things start feeling more painful :)

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Thanks for the update!

I refactored the get_on_deck_entry method and the code for the home route, and it should be cleaner now.

I tried using as much existing code as possible and calling e.book.load_percentage(username, e) but this always returned 0.0

In the home route method, I tried

percentage = on_deck_entries.map do |e|
    e.book.load_percentage username, e.title
end

and it returns the percentage correctly.

Could I add this method into the Entry class? Didn't feel very DRY to do this though.

If we will be using the method a lot, feel free to add it, but I would suggest naming it Entry.load_percentage for consistency.

so it would be good if we could just call e.load_progress in the view without having to pass in the username variable.

We need the env variable in route methods to know who the logged-in user is. I can't think of a way to do it in the Entry class. Maybe I missed something? Also, could you elaborate a bit on the UserEntry class you mentioned? Why do we need it?

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Also, the new section is titled "On Deck", but I think you mentioned that the section would be called "Continue Reading" but functions as the "On Deck" sections in Plex? I think "Continue Reading" is easier to understand, and it means pretty much the same thing in our case. Anyway, let me know what you think!

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

I saw your comment about DRY'ing the frontend HTML code, and I absolutely agree. The frontend code is ugly and it's getting harder to maintain. I have been planing to do a complete rewrite using a modern JS framework like React or Vue, but I just couldn't find the time to do it.

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Much cleaner! Thank you :)

I've added your percentage approach and it worked fine. I must have been doing something wrong.

Have now refactored all "On Deck" references to "Continue Reading" (this was just a holdover from the old code I wrote before we agreed to merge the two sections).

RE: Frontend framework. Time is always the enemy! I've toyed a tiny bit with Vue and seemed to get on with it better than React. But Javascript has never been my strong point and don't think I have enough experience to recommend or be that much help in this area :/

Further ideas / still todo

The basic version of the feature is largely done. I have some further thoughts and ideas below but I'd like your feedback on a) what you agree with, and b) what should we include in this issue vs spinning off as a separate issues/features (I guess it's to decide if you're happy to keep iterating on the home screen here or if you want to close off the work and then explore further in new issues).

  • Order by last read - I think people expect the most recent title they've read to be first in the Continue Reading list (ie. left most). If I'm reading 10 titles, I would expect the one I read yesterday to show before the one I last read a month ago. I believe this would require introducing a new section in info.json (I mocked up an example in this comment above)
  • Configurable "Continue Reading" settings with sane defaults - At the moment we show all titles you have started reading, even if you last read it 2 years ago. Do we want to introduce some form of "max weeks" / "max total entries". There's a lot to think about here as if you are up to date with a manga and the only reason you haven't read a title in a while is because you're waiting for it to be published, ideally you would want this to show in "Continue Reading". Plex solves this by always showing season premieres ie. S0XE01 but it doesn't seem as straightforward with manga. There is an element of YAGNI / premature optimisation here and I'm inclined to spin this out to think about later. Plex settings as an example:
    plex-ondeck-settings
  • Recently Added - New section on home page, under "Continue Reading". The purpose is to aid discoverability of new titles for users. The final form of this would ideally be intelligent enough to group multiple entries of the same title together (so you don't get one big long list of 20 entries for the same title). I think this would require adding another section to info.json eg. date_added as I don't think mtime will suffice.
  • Onboarding for new users (empty home screen) - In its current form, new users and new libraries will hit an empty screen on / :( This could be partially offset by having the Recently Added section but I wonder if we have some explanatory text that explains to users what they'll see once they start reading and direct them to the Library page to get started? Quick mockup:
    onboarding
  • Other possible sections for Home screen - eg. Recently Published, Start Reading, Rediscover, Top Rated. I think this should spin off into another issue. Some are possible eg. Start Reading, some depend on whether we implement other features above eg. Rediscover and some would only be possibly if we integrated with a 3rd party data source (Recently Published and Top Rated). If time was no object I think they would be nice features to have but I don't think these are a priority.

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

RE: UserEntry class. I clearly haven't properly thought this through :) I have most experience with Rails apps and using Rails with Devise (for auth) you get a really nice helper method current_user. In your controllers you create the objects needed in the view, and if the object should be limited to the user you can initialise it with eg. titles = current_user.context.library.titles (pseudo code). This means in your views, all of the attributes and class methods you reach for are already limited to what is available to the user:

<%- titles.each do |t| -%>
  <p>Percentage: <%= t.load_percentage %></p> <!-- Don't have to pass the user for each method -->
<%- end -%>

In a way this is just magic / syntactic sugar, but something like this could perhaps help down the line when you're looking to bring in filtering and visibility of multi libraries per user etc. Obviously I'm breezing over a lot of the complexity here and am probably being a bit naive with things. It's probably something you'd want to reach to a shard to help you solve. Anyway, this is way off scope. I'll leave this as food for thought for some future time!

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

I prefer keeping the relevant discussions in this issue as it's all about the home screen. We can open separate issues when working on the Plex theme or new progress indicators, etc.

I am thinking maybe we should allow the users to jump to the corresponding title page from a "Continue Reading" entry. Maybe we can add a "Go to Manga" button in the pop-up modal box? Let me know what you think :-)

Onboarding for new users

You are right and I haven't thought about this. I like your mockup and I can try to implement it. I think we should do something similar on the library page when the library is empty, but let's focus on the home screen first!

Order by last read and Recently Added

Yes I think we should have these two features ready before publishing a new version featuring the new home screen, and yes we should add the new fields in info.json. The "Recently Added" section would be particularly useful when we have the MangaDex auto-update feature (see #24). With the extra info saved in the JSON file, we can also have more sorting options in the library and title pages.

Your example info.json looks good, and I would suggest adding a time zone field just in case the local time zone changes. See https://crystal-lang.org/api/0.34.0/Time.html

Configurable "Continue Reading" settings

I think this feature would be nice to have but not pressing. It would be great if you have the time to work on it, otherwise, we can simply hardcode a limit (say 8 or 12) for the number of continue reading entries.

Other possible sections for Home screen

Yeah the extra sections you listed would indeed require external data sources, and I don't think a "Start Reading" section is necessary. The "Continue Reading" section we have now kind of acts like that, and the user can always visit the library page to "start reading". But maybe I misunderstood what you meant and in the case please let me know!

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Jump to title page

Yes, definitely agree. There are quite a few buttons in the modal already and I've mocked up a slightly modified approach below. Inspired by Plex (as always!). My reasoning:

  • Leave all the buttons to be about that specific entry
  • Introduce a link (clear hierarchy of buttons for entry and links as secondary actions, while trying to not make the UI too busy)
  • Use actual manga title as link text (there is a slight reduction in first time usability as users may need to click the link to learn where it goes, but after that it seems clearer that you click the actual title to go to the title. I did wonder if someone might see "Go to Manga" and be confused, asking "Aren't I already going to the manga? Ie. going to read this manga entry" <-- I could be over thinking this). I guess we could also try Go to [Ghost in the Shell] but the "Go to" will be superfluous after the first use.

Anyway, not beholden to any of this. Just an idea :)

continue-reading-modal

Onboarding for new users

I'm happy to have a first go at this if it will help? I'm sure you have plenty of other things going on too.

Order by last read and Recently Added

Sounds good, I will proceed with these two.

Can you talk a bit more about the time zone field? I was planning to save the times in utc. Do you mean if the server time changes or the end user's? What is the implication?

Configurable "Continue Reading" settings

👍 I'll hardcode it for now but will have a think about this in the background.

Other possible sections for Home screen

By "Start Reading" I mean it would only show you titles for which you have not started at all. You're right that it's really just a shortcut to going to your library and sorting by Progress. I guess as your library gets bigger it might be a nice thing as a way to remind you of titles you haven't started. It's just another avenue for discoverability but don't think it's very important for now.

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

I'm happy to have a first go at this if it will help? I'm sure you have plenty of other things going on too.

Of course! That would be great 👍

Can you talk a bit more about the time zone field? I was planning to save the times in utc. Do you mean if the server time changes or the end user's? What is the implication?

Ah I thought you will just store the local time which might cause problems when the server time zone changes. If we are saving the time in UTC, perhaps we can make it more explicit? E.g.,

2016-02-15 10:20:30 UTC

One of the reasons I prefer using info.json over SQLite is that the data is more accessible to the users. Seeing implicit UTC time might be a bit confusing for them.

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

About the link to go to the title page, your mockup looks awesome! You're a great UX designer :D

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Hi @hkalexling sorry for the slow movement on my end. Have had some work stuff I've had to take care of.

I'm currently implementing the last_read property into the info.json file. I'm a bit stuck on the load_last_read method and wondering if you can help? The basic gist of what I'm trying to do is below.

https://github.com/hkalexling/Mango/blob/e99d7b8b29db5e112390ea34fd6106a501655382/src/library.cr#L331-L341

Very similar to your load_progress method. Essentially, return the value if it exists in the file. I'm getting hung up on the strictness of Crystal and can't get it to work! :/ It either doesn't like the fact that sometimes the var doesn't exist, or there's some conflict with the var expected to be Time when sometimes it's nil? Unlike your load_progress method I can't really set the var initially as a Time object. As a hack, I did try setting last_read = Time.utc + 1.year and then checking if it's in the future it would assume it doesn't exist in the file and return nil, but couldn't get that to work either. I've tried a bunch of different things but perhaps you can give me some quick guidance? :)

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Sure! I made some comments in your commit.

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

When you have a sec would be great to get your feedback on my latest commit.

I have implemented the Order Continue Reading by last read feature. I still feel like I'm fighting Crystal more than I'm productively coding :D That is to say, I got the thing working but if you think there's a completely different approach that would be better please let me know.

NB. I'm saving Time.utc directly into the json and this stores using the format "2020-05-29T15:27:54Z" (the Z denotes UTC). Is that ok? Alternatively we could use to_s which would give us the explicit UTC, but we'd need to convert back when we read the file etc.

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Sorry for the delay! I've made some comments there :)

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

I'm thinking about the implementation for the date_added property (so we can show and order the Recently Added section). It's complicated by the fact that for existing users, entries will already exist. For new entries, simply setting the date during the scan and doing nothing if the date already exists is fine. However, how best to handle existing entries?

  1. We could do a one-time scan & update, so all entries without date_added would be set with Time.utc ie. now. This is easiest for us but it does mean entries will appear that were not recently added (probably not ideal).
  2. Alternatively, we could set all existing entries as eg. date_added: null and then handle this case in the code?
    • How do we know that the scan has run (successfully) and we don't need to run it again? Add something to the config? Feels annoying that we have to introduce a setting for a one-off job.
  3. Some other approach...?

I'm leaning towards option 2 but wanted to see what you think.

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Yeah, I agree it's quite complicated with many edge cases to consider. I have been thinking about this the whole time but I couldn't come up with a reasonable solution that works in all situations :(

I have a proposal but it's completely different from what we have planned, so I would like to know what you think.

On Unix, the OS stores three timestamps for each file: atime, ctime and mtime. atime is the time the file was last read, ctime is the time that the file's attributes (e.g., permissions and owners) were last modified, and mtime is the time that the file's content was last changed. Unfortunately, the file creation time is only available on some file systems, but I think we can use ctime to "approximate" the creation time. With this we don't need to store the date_added data in info.json, and we don't need to bother with all the edge cases.

However, Crystal removed the API to access ctime for portability issues (see crystal-lang/crystal#5584 (comment)). There's an open issue proposing to add in cross-platform ctime and atime supports (crystal-lang/crystal#8357), but it's currently stalled.

So my plan is to write a simple C binding that reads the ctime of a file and use that to approximate the file creation time. We don't have to support Windows (at least for now), so we don't need to care about portability. What do you think?

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

My main concern with using the file timestamps is that they are not necessarily a true proxy for when the file was added to Mango. You could have a file on your harddrive (not in Mango yet) from a couple of months ago. If you moved it in today, it's possible that it won't even show in the Recently Added section as there are too many newer entries in the list (assuming my understanding is correct).

I also don't know enough about the internal behaviour of ctime. I primarily use Windows (although I heavily use WSL which Mango works great in). I know in Windows when you download an old file the original timestamp remains. Is it possible for a similar scenario with ctime? Eg. you download a file originally released in 2010 and that ctime stays as 2010?

I am happy to persevere for a while with the more explicit date_added approach and see if I get anywhere. Other than the issue regarding handling existing entries that I mention, are there other concerns you have that I should think about as well?

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

The nice thing about ctime is that whenever the file is moved, its ctime resets to the current time. The same thing happens when downloading a file. Here's a quick experiemnt to illustrate:

alex_ling@do-sg:~$ touch a
alex_ling@do-sg:~$ stat a
  File: a
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: fc01h/64513d	Inode: 260261      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/alex_ling)   Gid: ( 1000/alex_ling)
Access: 2020-06-03 16:51:04.660381291 +0000
Modify: 2020-06-03 16:51:04.660381291 +0000
Change: 2020-06-03 16:51:04.660381291 +0000
 Birth: -
alex_ling@do-sg:~$ mkdir b && mv a b
alex_ling@do-sg:~$ stat b/a
  File: b/a
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: fc01h/64513d	Inode: 260261      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/alex_ling)   Gid: ( 1000/alex_ling)
Access: 2020-06-03 16:51:04.660381291 +0000
Modify: 2020-06-03 16:51:04.660381291 +0000
Change: 2020-06-03 16:51:14.924516830 +0000
 Birth: -

Notice that the Change time of the file a changes when it's moved.


How do we know that the scan has run (successfully) and we don't need to run it again? Add something to the config? Feels annoying that we have to introduce a setting for a one-off job.

I am not sure I understand this. The scanning process runs periodically. And what do you think should be added to the config?

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Ah, that's perfect than. And even if you move your library or rename your title folder it doesn't modify the file ctime (on the same host at least).


RE: scan - I meant the one-off scan & update job that would run on server start to set the date_added: null for all existing files. If we went with this approach we'd need to know that the one-off job had run successfully so it wouldn't run the next time the server was started (because we would want new files to have date_added: {current time} rather than continue to set NULL for everything. With your ctime approach this is unnecessary.

I guess if we really wanted we could read the ctime value and store this into date_added, after which Mango reads from the json file? After doing a bit of reading:

ctime gets updated when the file attributes are changed, like changing the owner, changing the permission or moving the file to an other filesystem

It's possible ctime could be modified and this would break user expectations. Or am I worrying too much and is this overkill? :)

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Ah now I see what you meant. Yes, I was thinking the same thing - how to properly initialize the date_added field for all entries, and I couldn't find a satisfactory solution. The user might stop Mango when the initialization is in progress.

I don't like the idea of adding a new config option either. I suppose we can add a special table into the SQLite DB to store these "states". For example, we can set a key to 0 before the initialization, and set it to 1 when it's finished. Still, it sounds hacky. Also, the initialization might take a long time if the library contains many archives.

Even if we are saving ctime as date_added for all entries, we will face the above issues.


Yes, ctime will change when the file's metadata is updated, or when the file's content is modified, and I don't think people will edit their manga archives.

Now let's consider some common operations that would change the ctime:

  • Moving the file to another directory: If I manually moved an archive, I would expect it to show up in the "Recently Added" section.
  • Renaming the file: Same as above.
  • Changing the owner and permissions: I agree this could break user expectations. But I am not sure if it's worth doing the above null initialization hack to prevent this.

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

I think it's possible to have the best of both worlds. What if the load_date_added method looks in info.json and if it it doesn't exist it reaches for the ctime value and then assigns it to date_added in info.json? Subsequent calls to load_date_added will then always grab from info.json avoiding any issues caused by owner or permission changes.

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Pushed latest code.

  • Refactored continue reading method in Library class and cleaned up home route (commit)
    • I have kept 2 private methods as I feel it aids readability, but let me know what you think
  • First working version of Recently Added section on Home (commit)
  • For now, I have set a hard cap of 12 entries for both sections (we can easily change this and make it configurable later)

Please let me have your feedback.

What I'm planning to look at next:

  • Intelligently group Recently Added by Title if multiple entries in a row
  • Onboarding for new users (on Home page)
  • Are you ok for me to experiment with introducing a Slider so that each section will only appear on one row? This is the same design as Plex, which I like because you don't lose where you are as you scroll down the page (currently, even with just 2 rows you lose the title and could forget if you're looking at Continue Reading or Recently Added).

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

The code looks good and works perfectly! Good job on that :D

Group recently added entries and home page onboarding: Yes, these are definitely needed. Please go ahead!

Slider: I see your point, but I am a bit concerned about the fact that users will have to click a few times to see the entries at the end of each section, while in the current state they can just scroll down and browse through them. Perhaps enabling autoplay would improve the experience?

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

No comments to refactor? I need to celebrate, thank you :)

Group recently added entries and home page onboarding: I'll focus on these for now 👍

Slider: I'm not a big fan of autoplay. Although it does a good job to showcase the content and teach users that there is more content then is shown, I find it can be quite distracting. You may be trying to read a title and it keeps moving, you may be trying to click a link and it moves away, which can be frustrating. I think it's a better user experience if the user is in control of scrolling or clicking.

But I agree that there is a discoverability problem to solve for first time users. Once a user discovers that they can scroll (or click) to see more content horizontally they should understand that this concept works for all sections on the Home screen (it's just Continue Reading and Recently Added for now, but if we do end up adding other sections - and/or allowing the user to configure which sections show on Home - then they should know that each section is usable in the same way, by scrolling horizontally).

Regarding clicking, I would configure it so that when you click the 'next' icon it doesn't just show 1 new entry but jumps to show all new entries (ie. if 4 columns showing entries 1 to 4, clicking Next will show 5 to 8, not 2 to 5).

Once a user knows they can scroll horizontally, there is effectively no difference to scrolling vertically. I would argue the 'Next' icons are there primarily to aid discoverability, to show that more content is available. For users on mobile and tablet touch screen devices, the horizontal scrolling should be quite natural (and we have Netflix to thank for teaching the UX pattern to a lot of people). For Laptop users you can two-finger horizontally scroll using your trackpad but perhaps not all users know this. For desktops you can hold Shift + Mouse scroll for horizontal scrolling, but again perhaps not all users know this. Perhaps we could show some one time messaging to teach users about this?

Other changes I've been thinking about to show more content are:

  • Better user of horizontal space. For reading text, setting a max-width makes it much easier to read so you're not struggling to the find the next line. But for individual entries, I think it could be a good idea to use more of the horizontal space (quick hacky mockup)
  • Slightly smaller default items. I admit that perhaps this is more personal preference, but it would allow us to show more content. We could always introduce a Plex-like size slider (animated gif)

Anyway, I'm getting away from the main focus here and I've ended up writing a bit of an essay :/

Perhaps I could work on the Slider separately as an experiment?

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Good points! You've convinced me autoplay is a bad idea :) Personally, I don't like one-time messages/tutorials as they can be a bit intrusive, and they are not easy to implement right. As a visual cue to let users know there are more entries available, perhaps we can add a dotnav to the slider?

I agree we should make better use of the horizontal space and make the cards and text smaller. I've been using the default styles came with UIKit but we should be able to tweak it easily. I feel that a slider to change the item size is kind of an overkill at this stage, and again I guess it's not easy to implement.

Feel free to experiment with the slider, but it would be great if you could submit a PR to merge the current branch to dev after finishing the entry grouping and user onboarding features. This branch is quite far behind dev, so I would need some time to resolve the conflicts and make some extra editings to make the new features (e.g., base URL and OPDS) work on the new home page.

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Thinking about it a bit more I agree regarding one-time messages. A good UI should inform without needing them.

I'll experiment separately with the Slider and dotnav and report back. But will focus on the PR after the last two things. For future reference, if I'm creating a new branch is it better if I branch from dev or master? For this branch I split from master, shall I merge current master into it before submitting the PR, will that help you? I need to remind myself to merge the original branch back in regularly, sorry I haven't done that on this one.

My todos

  • Group Recently Added entries by Title
  • Onboarding
  • Prep PR

Later / separate issues

  • Experiment with Slider and dotnav
  • Better use of the horizontal space and make the cards and text smaller

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Hmmm, I seem to have broken my local version of Mango :(

Whenever I try to access the site it says Waiting for localhost... forever. The console looks normal:

jaredt:Mango (feature/home)$ make run
crystal run src/mango.cr --error-trace
[INFO]    2020/06/07 14:03:01 | Scanned 2 titles in 110.915ms

I have reverted to my last known good commit and still seeing the issue. Have you encountered anything like this before? I'll see if you have any advice otherwise my next move will be to clone the repo again.

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Pushed for final feedback before PR - commits

  • Recently Added grouped by neighbouring Titles
  • Onboarding for various states:

Empty Library
empty-library

New user (not read any entry yet)
never-read

Existing user without any entries in Continue Reading and nothing in Recently Added (rare scenario but handling rather than showing a blank screen)
no-continue-reading-no-recently-added

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Wow, that was fast! I've left some comments. Thanks for your efforts 👍

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

v0.6.0 has been released. Thanks a lot for your help :D

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

@hkalexling I've just noticed that the Recently Added section works slightly different than I expected. I see you have refactored the method and I wonder if the change in behaviour was intentional?

My original thinking with the Recently Added section was for it to act as a timeline. In its dumbest form it would list the entries, in order, newest to oldest. The important thing from the user's perspective is that the entries and their order do not change. Their position in history is fixed, thus their position in the Recently Added list is fixed.

Now it is a common case that a bunch of chapters for the same title will be added at the same time (eg. a friend tells you about a new manga so you download all the chapters). Rather than have the Recently Added list be completely filled up with the single title, it makes sense to intelligently group these together. But, at least in the way I was originally thinking, it would still act as a timeline. So if you added 3 entries for Manga A last week and another entry today, it would show 2 items in the Recently Added list.

In its current form (v0.6.1), a title will only appear once in the list, so if 2 entries were added three weeks ago and a new entry was added today, the old 2 new entries item will disappear and a new 3 new entries item will appear at the start of the list. This approach isn't bad, per se, just different. Although, I would argue that it is slightly more ambiguous as to "what" is recently added. I think it may be slightly harder for the user to build a mental model of how the section works. Eg.

Original state (newest to oldest):

  • One Punch-Man 1 new entry
  • Ghost in the Shell 1 new entry
  • Hajime no Ippo 2 new entries

New state:

  • Hajime no Ippo 3 new entries
  • One Punch-Man 1 new entry
  • Ghost in the Shell 1 new entry

Looking at this, we know that 1 new Hajime no Ippo entry was added today, but for an end user, without knowledge of the inner workings, it may be unclear.

  • "Have 3 new entries been added today?"
  • "What happened to the Hajime no Ippo item that I'm sure was there after Ghost in the Shell?"

My preferred new state (historical timeline is immutable):

  • Hajime no Ippo 1 new entry
  • One Punch-Man 1 new entry
  • Ghost in the Shell 1 new entry
  • Hajime no Ippo 2 new entries

NB. this would actually go a step further than my previous implementation. The 'grouping' should only group for a unit of time (using a 'day' seems most reasonable), otherwise if you only add chapters for a single title it would still cause the same grouping issue. Eg.

  • Hajime no Ippo 1 new entry

>> 2 weeks pass, no new entries for any titles. Today, add 1 new entry for Hajime no Ippo:

Current new state:

  • Hajime no Ippo 2 new entries

Preferred new state:

  • Hajime no Ippo 1 new entry
  • Hajime no Ippo 1 new entry

What do you think? Am I just overcomplicating things? There's something about the mutable list that irks me but I can't tell if it's just because it wasn't what I originally planned.

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

Ah sorry about that! I didn't know that was intentional. I thought it was incorrectly implemented and that's why I refactored it.

Actually I don't have a strong opinion on this, and both options sound fine to me. I wish we had more contributors/core team members to share their views on these matters :( Do you know how the "recently added" section works in Plex? I can experiment with it and see how they handle this.

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

No problem!

Plex works basically as I have described. I unashamedly 'steal' from their UX unless I can find fault in it :) Unlike us, they have the benefit of a full-time team and I assume have done a bunch of research to make the UX super simple. It's always nice to be able to take advantage of their hard work!

The only thing I'm not sure about is their grouping date range. It's definitely less than a week as all the weekly release TV shows appear as separate entries, but I think it's more than a day as I feel like a series may complete over a few days but it still groups it together.

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

I see. I agree it's better to follow their design. I will refactor the method again to bring back the original behavior. I will also experiment with the date range to find a good default value.

BTW, is there a specific reason for you to use three months as the threshold for "recently added"? I find the time span a bit too long to call it "recent", and I prefer setting it to one month. What do you think?

from mango.

jaredlt avatar jaredlt commented on May 20, 2024

Sounds great, thank you!

RE: 3 months. No, I think I plucked that from the air. 1 Month sounds good to me 👍

from mango.

hkalexling avatar hkalexling commented on May 20, 2024

The grouping behavior has been updated in v0.7.0 to respect your original design. I have used 1 day as the time limit for grouping neighboring entries.

from mango.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.