Strypper / mauisland

MAUIsland 🏝️ is the number 1 controls gallery for .NET MAUI
MIT License
198 stars 14 forks source link

184 get issues by labels then save them to localdb #192

Closed Strypper closed 8 months ago

Strypper commented 8 months ago

COOL NEW FEATURE!!!!

Service name: IGitHubIssueLocalDbService

Page name: ActivityIndicatorPage

Contributors

Describe your changes

In the latest update, the mechanism for retrieving GitHub issue lists has been significantly optimized. Upon the initial visit to the respective page, issue data is now cached in a local database. Subsequent accesses to this page will leverage this cache to fetch issue information, bypassing the need for direct GitHub API calls. This approach enhances the application's performance and mitigates potential rate limiting issues associated with frequent API requests.

Feature

To facilitate these improvements, the feature logic has been modularized into a dedicated project, MAUIsland.Features.LocalDbFeatures.GitHub. This project works in tandem with the foundational MAUIsland.Features.LocalDbFeatures, ensuring a cohesive and maintainable codebase.

Viewmodel

The implementation of this caching strategy is managed within the ViewModel. This design choice allows for a seamless integration with existing data retrieval processes, utilizing the IGitHubService for initial data acquisition from the GitHub API. This strategic placement of logic within the ViewModel layer ensures that our application remains responsive, efficient, and capable of scaling to meet future requirements.

Support functionalities

namespace MAUIsland.Features.LocalDbFeatures.GitHub;

public interface IGitHubIssueLocalDbService : ILocalDbService<GitHubIssueLocalDbModel>
{
    /// <summary>
    /// Get list of issues related to a control.
    /// </summary>
    /// <param name="controlName"></param>
    /// <returns></returns>
    Task<IEnumerable<GitHubIssueLocalDbModel>?> GetByControlNameAsync(string controlName);

    /// <summary>
    /// Get single issue by its url.
    /// </summary>
    /// <param name="issueUrl"></param>
    /// <returns></returns>
    Task<GitHubIssueLocalDbModel?> GetByIssueUrlAsync(string issueUrl);
}

Usage (ViewModel):

Retrieve the github issues from cached first

        // First: sync from local db.
        // TODO: how to get control name?
        var allLocalDbIssues = await GetIssueByControlNameFromLocalDb(ControlInformation.ControlName);

        // If localdb version is not null & not outdated => use local version.
        if (allLocalDbIssues != null && allLocalDbIssues.Any() && !allLocalDbIssues.Any(x => (now - x.LastUpdated).TotalHours > 1))
        {
            if (ControlIssues is null || forced)
            {
                ControlIssues = new(allLocalDbIssues.Select(x => new ControlIssueModel()
                {
                    IssueId = x.IssueId,
                    Title = x.Title,
                    IssueLinkUrl = x.IssueLinkUrl,
                    MileStone = x.MileStone,
                    OwnerName = x.OwnerName,
                    AvatarUrl = x.UserAvatarUrl,
                    CreatedDate = x.CreatedDate,
                    LastUpdated = x.LastUpdated
                }));
            }
            IsBusy = false;

            // Done.
            return;
        }

Save issue down to the local database

    private async Task UpdateLocalIssue(GitHubIssueModel issue)
    {
        try
        {
            var now = DateTime.UtcNow;

            var localIssue = await gitHubIssueLocalDbService.GetByIssueUrlAsync(issue.Url);

            if (localIssue is null)
            {
                await gitHubIssueLocalDbService.AddAsync(new()
                {
                    IssueId = issue.Id,
                    Title = issue.Title,
                    IssueLinkUrl = issue.Url,
                    ControlName = ControlInformation.ControlName,
                    MileStone = issue.Milestone?.Title,
                    OwnerName = issue.User?.Login,
                    UserAvatarUrl = issue.User?.AvatarUrl,
                    CreatedDate = issue.CreatedAt.DateTime,
                    LastUpdated = now
                });
                return;
            }

            // Update fields: milestone (TODO: what else?).
            localIssue.MileStone = issue.Milestone?.Title;
            localIssue.LastUpdated = now;

            await gitHubIssueLocalDbService.UpdateAsync(localIssue);
        }
        catch (Exception)
        {
            // TODO: should do something.
            return;
        }
    }

Have we discussed about this before ? (Please link the discussion link below)

Yes in discord