示例#1
0
        public SettingsViewModel(
            ITranslationsService translationsService,
            IFilePickerService filePickerService,
            IPackagingService packagingService,
            ISettingsService settingsService,
            IPlatformService platformService,
            IDialogService dialogService,
            IOpmlService opmlService)
        {
            Theme   = string.Empty;
            Version = packagingService.Version;
            (LoadImages, NeedBanners) = (true, true);
            (FontSize, NotifyPeriod, MaxArticlesPerFeed) = (0, 0, 0);
            LeaveFeedback = new ObservableCommand(packagingService.LeaveFeedback);
            LeaveReview   = new ObservableCommand(packagingService.LeaveReview);
            ImportOpml    = new ObservableCommand(async() =>
            {
                var stream = await filePickerService.PickFileForReadAsync();
                await opmlService.ImportOpmlFeedsAsync(stream);
            });
            ExportOpml = new ObservableCommand(async() =>
            {
                var stream = await filePickerService.PickFileForWriteAsync();
                await opmlService.ExportOpmlFeedsAsync(stream);
            });
            Reset = new ObservableCommand(async() =>
            {
                var response = await dialogService.ShowDialogForConfirmation(
                    translationsService.Resolve("ResetAppNoRestore"),
                    translationsService.Resolve("Notification"));
                if (response)
                {
                    await platformService.ResetApp();
                }
            });
            Load = new ObservableCommand(async() =>
            {
                await Task.WhenAll(
                    StartTracking(NotifyPeriod, "NotifyPeriod", platformService.RegisterBackgroundTask),
                    StartTracking(MaxArticlesPerFeed, "MaxArticlesPerFeed", o => Task.CompletedTask),
                    StartTracking(NeedBanners, "NeedBanners", o => Task.CompletedTask),
                    StartTracking(LoadImages, "LoadImages", o => Task.CompletedTask),
                    StartTracking(FontSize, "FontSize", o => Task.CompletedTask),
                    StartTracking(Theme, "Theme", platformService.RegisterTheme)
                    );
            });
            async Task StartTracking <T>(ObservableProperty <T> property, string key,
                                         Func <T, Task> callback) where T : IConvertible
            {
                property.Value = await settingsService.GetAsync <T>(key);

                property.PropertyChanged += async(o, args) =>
                {
                    var value = property.Value;
                    await callback.Invoke(value);

                    await settingsService.SetAsync(key, value);
                };
            }
        }
示例#2
0
        private Inline GenerateImage(HtmlNode node)
        {
            if (!_loadImages)
            {
                return(new Span());
            }
            var reference = node.Attributes["src"]?.Value;

            if (!Uri.IsWellFormedUriString(reference, UriKind.Absolute))
            {
                return(new Span());
            }
            var sourceUri = new Uri(reference, UriKind.Absolute);
            var image     = new Image
            {
                Source = new BitmapImage(sourceUri)
                {
                    CreateOptions = BitmapCreateOptions.IgnoreImageCache
                },
                Stretch             = Stretch.Uniform, VerticalAlignment = VerticalAlignment.Top,
                HorizontalAlignment = HorizontalAlignment.Center, MaxHeight = 500,
                Margin = new Thickness(-12, 12, -12, 12), Opacity = 0
            };

            image.ImageOpened += (sender, e) =>
            {
                var bmp = (BitmapImage)image.Source;
                if (bmp.PixelHeight >= bmp.PixelWidth)
                {
                    image.Margin = new Thickness(0, 12, 0, 12);
                }
                image.Fade(1, 300, 100).Start();
            };
            image.RightTapped += (sender, e) =>
            {
                var launcher = new MenuFlyoutItem {
                    Text = _translationsService.Resolve("ImageOpenFullSize")
                };
                var copier = new MenuFlyoutItem {
                    Text = _translationsService.Resolve("ImageCopyLink")
                };
                copier.Click   += (s, o) => _platformService.CopyTextToClipboard(sourceUri.AbsoluteUri);
                launcher.Click += (s, o) => _platformService.LaunchUri(sourceUri);
                new MenuFlyout {
                    Items = { launcher, copier }
                }.ShowAt(image);
            };
            var inlineUiContainer = new InlineUIContainer {
                Child = image
            };
            var span = new Span();

            span.Inlines.Add(inlineUiContainer);
            span.Inlines.Add(new LineBreak());
            return(span);
        }
示例#3
0
        public ChannelsViewModel(
            ICategoriesRepository categoriesRepository,
            ITranslationsService translationsService,
            INavigationService navigationService,
            IFactoryService factoryService,
            IDialogService dialogService)
        {
            (IsEmpty, IsLoading) = (false, true);
            Items       = new ObservableCollection <ChannelCategoryViewModel>();
            OpenSearch  = new ObservableCommand(navigationService.Navigate <SearchViewModel>);
            AddCategory = new ObservableCommand(async() =>
            {
                var name = await dialogService.ShowDialogForResults(
                    translationsService.Resolve("EnterNameOfNewCategory"),
                    translationsService.Resolve("EnterNameOfNewCategoryTitle"));
                if (string.IsNullOrWhiteSpace(name))
                {
                    return;
                }
                var category = new Category {
                    Title = name
                };
                await categoriesRepository.InsertAsync(category);
                Items.Add(factoryService.CreateInstance <
                              ChannelCategoryViewModel>(category, this));
            });
            Load = new ObservableCommand(async() =>
            {
                IsLoading.Value = true;
                var categories  = await categoriesRepository.GetAllAsync();
                Items.Clear();
                foreach (var category in categories)
                {
                    Items.Add(factoryService.CreateInstance <
                                  ChannelCategoryViewModel>(category, this));
                }
                IsEmpty.Value   = Items.Count == 0;
                IsLoading.Value = false;

                // Subscribe on collection changed to perform items rearranging.
                Items.CollectionChanged += async(s, a) =>
                {
                    IsEmpty.Value = Items.Count == 0;
                    var items     = Items.Select(i => i.Category.Value);
                    await categoriesRepository.RearrangeAsync(items);
                };
            });
        }
示例#4
0
        public MenuViewModel(
            ITranslationsService translationsService,
            INavigationService navigationService,
            IPlatformService platformService,
            ISettingsService settingsService)
        {
            SelectedIndex = 0;
            Items         = new ObservableCollection <Tuple <string, object, ObservableCommand, Type> >();
            Load          = new ObservableCommand(async() =>
            {
                await navigationService.Navigate <FeedViewModel>();
                var theme = await settingsService.GetAsync <string>("Theme");
                await platformService.RegisterTheme(theme);
                var freq = await settingsService.GetAsync <int>("NotifyPeriod");
                await platformService.RegisterBackgroundTask(freq);
                await settingsService.SetAsync("LastFetched", DateTime.Now);
            });

            CreateItem <FeedViewModel>("FeedViewMenuItem");
            CreateItem <FaveViewModel>("FaveViewMenuItem");
            CreateItem <ChannelsViewModel>("SourcesViewMenuItem");
            CreateItem <SearchViewModel>("SearchViewMenuItem");
            CreateItem <SettingsViewModel>("SettingsViewMenuItem");
            navigationService.Navigated += (sender, args) =>
            {
                var first = Items.FirstOrDefault(x => x.Item4 == args);
                if (first == null)
                {
                    return;
                }
                SelectedIndex.Value = Items.IndexOf(first);
            };

            void CreateItem <T>(string key) where T : class
            {
                var type        = typeof(T);
                var command     = new ObservableCommand(navigationService.Navigate <T>);
                var translation = translationsService.Resolve(key);
                var icon        = navigationService.Icons[type];
                var tuple       = (translation, icon, command, type).ToTuple();

                Items.Add(tuple);
            }
        }
示例#5
0
        public async Task ImportFeedsFromLegacyFormat()
        {
            try
            {
                var imported = await ProcessFeedsFromLegacyFormat();

                if (imported)
                {
                    await _dialogService.ShowDialog(
                        _translationsService.Resolve("SourcesMigrateSuccess"),
                        _translationsService.Resolve("SettingsNotification"));
                }
            }
            catch (Exception exception)
            {
                var translation  = _translationsService.Resolve("SourcesMigrateFailure");
                var errorMessage = string.Format(translation, exception.Message);
                await _dialogService.ShowDialog(errorMessage,
                                                _translationsService.Resolve("SettingsNotification"));
            }
        }
示例#6
0
        public ArticleViewModel(
            ICategoriesRepository categoriesRepository,
            ITranslationsService translationsService,
            INavigationService navigationService,
            IFavoritesService favoritesService,
            ISettingsService settingsService,
            IPlatformService platformService,
            IDialogService dialogService,
            Article article)
        {
            Title         = article.Title;
            Feed          = article.FeedTitle;
            Content       = article.Content;
            PublishedDate = article.PublishedDate;
            IsFavorite    = article.Fave;
            IsRead        = article.Read;

            Open  = new ObservableCommand(() => navigationService.Navigate <ArticleViewModel>(this));
            Image = new ObservableProperty <string>(async() =>
            {
                var shouldLoadImages = await settingsService.GetAsync <bool>("LoadImages");
                return(shouldLoadImages ? article.ImageUri : null);
            });
            Share = new ObservableCommand(() =>
            {
                var shareMessage = string.Concat(
                    article.Title, Environment.NewLine,
                    article.Uri, Environment.NewLine,
                    "via myFeed for Windows Universal");
                return(platformService.Share(shareMessage));
            });
            CopyLink = new ObservableCommand(async() =>
            {
                await platformService.CopyTextToClipboard(article.Uri);
                await dialogService.ShowDialog(
                    translationsService.Resolve("CopyLinkSuccess"),
                    translationsService.Resolve("SettingsNotification"));
            });
            LaunchUri = new ObservableCommand(async() =>
            {
                if (Uri.IsWellFormedUriString(article.Uri, UriKind.Absolute))
                {
                    await platformService.LaunchUri(new Uri(article.Uri));
                }
            });
            MarkRead = new ObservableCommand(async() =>
            {
                IsRead.Value = article.Read = !IsRead.Value;
                await categoriesRepository.UpdateArticleAsync(article);
            });
            MarkFavorite = new ObservableCommand(async() =>
            {
                IsFavorite.Value = !IsFavorite.Value;
                if (IsFavorite.Value)
                {
                    await favoritesService.Insert(article);
                }
                else
                {
                    await favoritesService.Remove(article);
                }
            });
        }
        public ChannelCategoryViewModel(
            ICategoriesRepository categoriesRepository,
            ITranslationsService translationsService,
            IFactoryService factoryService,
            IDialogService dialogService,
            ChannelsViewModel channelsViewModel,
            Category category)
        {
            Category  = category;
            Title     = category.Title;
            SourceUri = string.Empty;

            Items          = new ObservableCollection <ChannelViewModel>();
            RenameCategory = new ObservableCommand(async() =>
            {
                var name = await dialogService.ShowDialogForResults(
                    translationsService.Resolve("EnterNameOfNewCategory"),
                    translationsService.Resolve("EnterNameOfNewCategoryTitle"));
                if (string.IsNullOrWhiteSpace(name))
                {
                    return;
                }
                category.Title = name;
                await categoriesRepository.UpdateAsync(category);
                category.Title = Title.Value = name;
            });
            RemoveCategory = new ObservableCommand(async() =>
            {
                var shouldDelete = await dialogService.ShowDialogForConfirmation(
                    translationsService.Resolve("DeleteCategory"),
                    translationsService.Resolve("DeleteElement"));
                if (!shouldDelete)
                {
                    return;
                }
                await categoriesRepository.RemoveAsync(category);
                channelsViewModel.Items.Remove(this);
            });
            AddSource = new ObservableCommand(async() =>
            {
                var sourceUri = SourceUri.Value;
                if (string.IsNullOrWhiteSpace(sourceUri) ||
                    !Uri.IsWellFormedUriString(sourceUri, UriKind.Absolute))
                {
                    return;
                }
                SourceUri.Value = string.Empty;
                var model       = new Channel {
                    Uri = sourceUri, Notify = true
                };
                await categoriesRepository.InsertChannelAsync(category, model);
                Items.Add(factoryService.CreateInstance <
                              ChannelViewModel>(model, this));
            });
            Load = new ObservableCommand(() =>
            {
                Items.Clear();
                foreach (var channel in category.Channels)
                {
                    Items.Add(factoryService.CreateInstance <
                                  ChannelViewModel>(channel, this));
                }
            });
        }