/// <summary> /// Конструктор. /// </summary> /// <param name="pageLink">Ссылка на страницу.</param> public BoardPageLoaderViewModel(BoardLinkBase pageLink) { if (pageLink == null) throw new ArgumentNullException(nameof(pageLink)); PageLink = pageLink; update = new StdEngineOperationWrapper<IBoardPageLoaderResult>(OperationFactory) { HighPriority = true }; update.Finished += UpdateOnFinished; update.ResultGot += UpdateOnResultGot; update.Started += UpdateOnStarted; PageNum = ServiceLocator.Current.GetServiceOrThrow<ILinkTransformService>().GetBoardPage(pageLink); AppHelpers.DispatchAction(async () => { var t = await BoardTitleHelper.GetBoardTitle(pageLink) ?? ""; Title = t; TitleWithPage = $"[{PageNum}] {t}"; }); var engine = ServiceLocator.Current.GetServiceOrThrow<INetworkEngines>().FindEngine(pageLink.Engine); if (engine != null) { CanInvokeCatalog = (engine.Capability & EngineCapability.Catalog) != 0; } else { CanInvokeCatalog = false; } }
/// <summary> /// Записать файл в медиа-хранилище (временный файл будет удалён). /// </summary> /// <param name="link">Ссылка.</param> /// <param name="tempFile">Временный файл.</param> /// <returns>Файл в хранилище.</returns> public async Task<StorageFile> MoveToMediaStorage(BoardLinkBase link, StorageFile tempFile) { var cacheDir = await GetCacheFolder(); var newFile = await cacheDir.CreateFileAsync(GetMediaFileName(link), CreationCollisionOption.OpenIfExists); await WriteCacheMediaFile(newFile, tempFile, true); return newFile; }
/// <summary> /// Конструктор. /// </summary> /// <param name="link">Ссылка.</param> public BigMediaSourceViewModel(BoardLinkBase link) : base(false) { if (link == null) throw new ArgumentNullException(nameof(link)); this.link = link; var linkTransform = ServiceLocator.Current.GetServiceOrThrow<ILinkTransformService>(); var fn = linkTransform.GetMediaFileName(link); if (fn == null) { Extension = null; } else { Extension = fn.Split('.').LastOrDefault()?.ToLowerInvariant(); } if (Extension == null) { SourceType = BigMediaSourceType.Static; } else { switch (Extension) { case "gif": SourceType = BigMediaSourceType.Gif; break; case "webm": SourceType = BigMediaSourceType.Webm; break; default: SourceType = BigMediaSourceType.Static; break; } } }
/// <summary> /// Удлаить данные постинга. /// </summary> /// <param name="link">Ссылка.</param> /// <returns>Таск.</returns> public async Task DeletePostingData(BoardLinkBase link) { var fileName = string.Format("{0}.cache", Services.GetServiceOrThrow<ILinkHashService>().GetLinkHash(link)); var file = await GetCacheFile(fileName); await file.DeleteAsync(); await RemoveFromSizeCache(fileName); }
/// <summary> /// Проверить страницу борды на наличие изменений. /// </summary> /// <param name="link">Ссылка.</param> /// <returns>Результат (null - невозможно проверить или ошибка проверки).</returns> public IEngineOperationsWithProgress<bool?, EngineProgress> CheckBoardPage(BoardLinkBase link) { if ((link.LinkKind & BoardLinkKind.BoardPage) == 0) { throw new ArgumentException("Неправильный тип ссылки"); } return new CheckObjectOperation(Services, link); }
/// <summary> /// Загрузить тред. /// </summary> /// <param name="link">Ссылка.</param> /// <param name="mode">Режим обновления данных.</param> /// <returns>Результат.</returns> public IEngineOperationsWithProgress<ThreadTree, EngineProgress> LoadThread(BoardLinkBase link, UpdateThreadMode mode = UpdateThreadMode.Default) { if ((link.LinkKind & BoardLinkKind.Thread) == 0) { throw new ArgumentException("Неправильный тип ссылки"); } return new LoadThreadOperation(Services, new LoadThreadOperationParameter() { Link = link, Mode = mode }); }
/// <summary> /// Загрузить страницу борды. /// </summary> /// <param name="link">Ссылка.</param> /// <param name="mode">Режим обновления данных.</param> /// <returns>Результат.</returns> public IEngineOperationsWithProgress<BoardPageTree, EngineProgress> LoadBoardPage(BoardLinkBase link, UpdateBoardPageMode mode = UpdateBoardPageMode.CheckETag) { if ((link.LinkKind & BoardLinkKind.BoardPage) == 0) { throw new ArgumentException("Неправильный тип ссылки"); } return new LoadBoardPageOperation(Services, new LoadBoardPageOperationParameter() {Link = link, Mode = mode}); }
/// <summary> /// Получить заголовок борды. /// </summary> /// <param name="link">Ссылка.</param> /// <returns>Заголовок.</returns> public static async Task<string> GetBoardTitle(BoardLinkBase link) { if (link == null) { return ""; } var engine = ServiceLocator.Current.GetServiceOrThrow<INetworkEngines>().FindEngine(link.Engine); if (engine == null) { return ""; } var linkTransform = ServiceLocator.Current.GetServiceOrThrow<ILinkTransformService>(); var boardLink = linkTransform.BoardLinkFromAnyLink(link); if (boardLink == null) { return ""; } var linkHash = ServiceLocator.Current.GetServiceOrThrow<ILinkHashService>(); var hash = linkHash.GetLinkHash(boardLink); var storage = ServiceLocator.Current.GetServiceOrThrow<IStorageService>(); string title = null; var favData = (await storage.ThreadData.FavoriteBoards.LoadLinkCollectionForReadOnly()) as BoardLinkCollection; if (favData?.BoardInfo != null) { if (favData.BoardInfo.ContainsKey(hash)) { title = favData.BoardInfo[hash].DisplayName; } } if (title == null) { var rootLink = engine.RootLink; var boards = await storage.ThreadData.LoadBoardReferences(rootLink); if (boards?.References != null) { var data = boards.References.FirstOrDefault(l => hash.Equals(linkHash.GetLinkHash(l?.Link))); if (data != null) { title = data.DisplayName; } } } if (title != null) { return $"/{linkTransform.GetBoardShortName(boardLink)}/ - {title.Trim()}"; } return $"/{linkTransform.GetBoardShortName(boardLink)}/"; }
/// <summary> /// Конструктор. /// </summary> /// <param name="link">Ссылка.</param> /// <param name="displayName">Отображаемое имя.</param> /// <param name="category">Категория.</param> /// <param name="isFavorite">Избранное.</param> /// <param name="isAdult">Для взрослых.</param> public BoardListBoardDataViewModel(BoardLinkBase link, string displayName, string category, bool isFavorite, bool isAdult) { if (link == null) throw new ArgumentNullException(nameof(link)); Link = link; DisplayName = displayName ?? ""; Category = category ?? ""; IsFavorite = isFavorite; IsAdult = isAdult; }
/// <summary> /// Конструктор. /// </summary> /// <param name="value">Значение.</param> /// <param name="name">Имя.</param> /// <param name="iconLink">Ссылка.</param> public PostingIconElement(int? value, string name, BoardLinkBase iconLink) { Value = value; Name = name; if (iconLink != null) { Image = new ImageSourceViewModel(iconLink); Image.Load.Start(); } }
/// <summary> /// Загрузить капчу. /// </summary> /// <param name="link">Ссылка.</param> public async void Load(BoardLinkBase link) { try { await DoLoad(link); } catch (Exception ex) { await AppHelpers.ShowError(ex); } }
/// <summary> /// Получить ключ. /// </summary> /// <param name="link">Ссылка.</param> /// <returns>Ключ.</returns> public INavigationKey GetKey(BoardLinkBase link) { if (link == null) { return null; } var t = link.GetType(); if (keyFuncs.ContainsKey(t)) { return keyFuncs[t](link); } throw new ArgumentException(string.Format("Неизвестный тип ссылки {0}", t.FullName)); }
/// <summary> /// Конструктор. /// </summary> /// <param name="link">Ссылка.</param> /// <param name="visited">Посещённые.</param> /// <param name="favorites">Избранные.</param> public VisitedMainTileViewModel(BoardLinkBase link, ThreadLinkCollection visited, ThreadLinkCollection favorites) { if (link == null) throw new ArgumentNullException(nameof(link)); this.link = link; TileData = new VisitedThreadTileViewModel(link); var upd = (IThreadTileUpdater)TileData; upd.UpdateData(visited); FavoritesChanged(favorites); hash = ServiceLocator.Current.GetServiceOrThrow<ILinkHashService>().GetLinkHash(link); if (visited?.ThreadInfo != null) { threadInfo = visited.ThreadInfo.ContainsKey(hash) ? visited.ThreadInfo[hash] : null; } }
/// <summary> /// Загрузить данные постинга. /// </summary> /// <param name="link">Ссылка.</param> /// <returns>Данные постинга.</returns> public async Task<PostingData> LoadPostData(BoardLinkBase link) { try { if (link == null) return null; var fileName = string.Format("{0}.cache", Services.GetServiceOrThrow<ILinkHashService>().GetLinkHash(link)); var file = await GetCacheFile(fileName); return await ReadXmlObject<PostingData>(file, true); } catch (Exception ex) { DebugHelper.BreakOnError(ex); return null; } }
/// <summary> /// Загрузить данные борды. /// </summary> /// <param name="link">Ссылка.</param> /// <returns>Страница борды.</returns> public async Task<BoardPageTree> LoadBoardPage(BoardLinkBase link) { try { if (link == null) return null; var fileName = string.Format(CacheConsts.CacheFileTemplates[CacheConsts.Board], Services.GetServiceOrThrow<ILinkHashService>().GetLinkHash(link)); var file = await GetCacheFileOrNull(fileName); return await ReadXmlObject<BoardPageTree>(file, true); } catch (Exception ex) { DebugHelper.BreakOnError(ex); return null; } }
/// <summary> /// Конструктор. /// </summary> /// <param name="link">Ссылка.</param> /// <param name="favorites">Избранные треды.</param> public FavoriteMainTileViewModel(BoardLinkBase link, ThreadLinkCollection favorites) { if (link == null) throw new ArgumentNullException(nameof(link)); this.link = link; TileData = new FavoriteThreadTileViewModel(link); var upd = (IThreadTileUpdater) TileData; var si = upd?.UpdateData(favorites); if (si != null) { UpdateId = new ThreadListUpdateId() { LinkHash = ServiceLocator.Current.GetServiceOrThrow<ILinkHashService>().GetLinkHash(link), SortDate = si.AddedDate, Link = link }; } else { UpdateId = new ThreadListUpdateId() { LinkHash = ServiceLocator.Current.GetServiceOrThrow<ILinkHashService>().GetLinkHash(link), SortDate = DateTime.MinValue, Link = link }; } }
/// <summary> /// Конструктор. /// </summary> /// <param name="link">Ссылка.</param> /// <param name="favorites">Избранные доски.</param> public FavoriteBoardMainTileViewModel(BoardLinkBase link, BoardLinkCollection favorites) { if (link == null) throw new ArgumentNullException(nameof(link)); this.link = link; string name = ServiceLocator.Current.GetServiceOrThrow<ILinkTransformService>().GetBoardShortName(link); var hash = ServiceLocator.Current.GetServiceOrThrow<ILinkHashService>().GetLinkHash(link); if (favorites?.BoardInfo != null) { if (favorites.BoardInfo.ContainsKey(hash)) { var bi = favorites.BoardInfo[hash]; name = bi.DisplayName; } } TileData = new BoardListBoardDataViewModel(link, name, "Избранные", true, false); UpdateId = new ThreadListUpdateId() { LinkHash = hash, SortDate = DateTime.MinValue, Link = link }; }
/// <summary> /// Получить файл из медиа-хранилища. /// </summary> /// <param name="link">Ссылка.</param> /// <returns>Файл (null, если не найден).</returns> public async Task<StorageFile> GetFromMediaStorage(BoardLinkBase link) { var fileName = GetMediaFileName(link); var hasFile = await FindFileInCache(fileName); if (!hasFile) { return null; } var cacheDir = await GetCacheFolder(); try { return await cacheDir.GetFileAsync(fileName); } catch (Exception ex) { DebugHelper.BreakOnError(ex); return null; } }
private void PushCurrentLink(IPostViewModel si, BoardLinkBase l) { if (si?.Link != null) { var linkHash = ServiceLocator.Current.GetServiceOrThrow<ILinkHashService>(); var oldHash = linkHash.GetLinkHash(si.Link); if (ViewModel?.FindPost(new LinkHashPostCollectionSearchQuery(oldHash)) == null) { return; } if (l != null) { var newHash = linkHash.GetLinkHash(l); if (newHash == oldHash) { return; } } singleNavigationStack.Push(oldHash); } }
private void PushCurrentLink(BoardLinkBase l) { var si = SingleSelectedItem as IPostViewModel; PushCurrentLink(si, l); }
private void RestoreTopPost() { var vm = ViewModel; if (vm == null) { return; } if (!isLoaded || !isTopPostSet) { return; } AppHelpers.DispatchAction(() => { var linkHash = ServiceLocator.Current.GetServiceOrThrow<ILinkHashService>(); var navigatedPostLinkVal = navigatePostLink; var saveTopHashVal = savedTopPostHash; this.navigatePostLink = null; this.savedTopPostHash = null; if (navigatedPostLinkVal != null || saveTopHashVal != null) { string checkHash; if (navigatedPostLinkVal != null) { checkHash = linkHash.GetLinkHash(navigatedPostLinkVal); } else { checkHash = saveTopHashVal; } var el = vm.Posts.FirstOrDefault(t => { var o = t?.Link; if (o == null) { return false; } return linkHash.GetLinkHash(o) == checkHash; }); if (el != null) { ScrollIntoView(el); } } return Task.CompletedTask; }, false, 50); }
private async Task SetStoredCurrentPost(BoardLinkBase threadLink, BoardLinkBase postLink, bool async = true) { try { var store = ServiceLocator.Current.GetServiceOrThrow<IStorageService>(); if (async) { await store.CurrentPostStore.SetCurrentPost(threadLink, postLink); } else { await store.CurrentPostStore.SetCurrentPostSync(threadLink, postLink); } } catch (Exception ex) { DebugHelper.BreakOnError(ex); } }
private async Task<string> GetStoredCurrentPostHash(BoardLinkBase threadLink) { try { var store = ServiceLocator.Current.GetServiceOrThrow<IStorageService>(); var linkHash = ServiceLocator.Current.GetServiceOrThrow<ILinkHashService>(); var link = await store.CurrentPostStore.GetCurrentPost(threadLink); if (link == null) { return null; } return linkHash.GetLinkHash(link); } catch (Exception ex) { DebugHelper.BreakOnError(ex); return null; } }
protected override async void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); var linkTransform = ServiceLocator.Current.GetServiceOrThrow<ILinkTransformService>(); var link = NavigationHelper.GetLinkFromParameter(e.Parameter); navigatedLink = linkTransform.GetThreadLinkFromAnyLink(link); navigatePostLink = null; if (link != null) { if ((link.LinkKind & BoardLinkKind.Post) != 0 && e.NavigationMode != NavigationMode.Back) { navigatePostLink = link; } } if (navigatedLink == null) { await AppHelpers.ShowError(new InvalidOperationException("Неправильный тип параметра навигации")); BootStrapper.Current.NavigationService.GoBack(); return; } savedTopPostHash = await GetStoredCurrentPostHash(navigatedLink); isTopPostSet = true; var vm = new ThreadViewModel(navigatedLink); ViewModel = vm; vm.PostsUpdated += LiteWeakEventHelper.CreateHandler(new WeakReference<ThreadPage>(this), (root, esender, ee) => root.OnPostsUpdated(esender, ee)); isBackNavigated = e.NavigationMode == NavigationMode.Back; vm.IsBackNavigatedToViewModel = isBackNavigated; vm.PropertyChanged += ViewModelOnPropertyChanged; ViewModelOnPropertyChanged(vm, new PropertyChangedEventArgs(null)); NavigatedTo?.Invoke(this, e); }
/// <summary> /// Загрузить маленький медиафайл. /// </summary> /// <param name="link">Ссылка.</param> /// <param name="mode">Режим загрузки.</param> /// <returns>Результат.</returns> public IEngineOperationsWithProgress<StorageFile, EngineProgress> LoadMediaFile(BoardLinkBase link, LoadMediaFileMode mode) { if ((link.LinkKind & BoardLinkKind.Media) == 0 && (link.LinkKind & BoardLinkKind.Youtube) == 0) { throw new ArgumentException("Неправильный тип ссылки"); } return new LoadMediaFileOperation(Services, new LoadMediaFileOperationParameter() {Link = link, Mode = mode}); }
/// <summary> /// Конструктор. /// </summary> /// <param name="link">Ссылка.</param> public ThreadNavigationTarget(BoardLinkBase link) { Link = link; }
/// <summary> /// Получение каталога. /// </summary> /// <param name="link">Ссылка.</param> /// <param name="mode">Режим обновления.</param> /// <returns>Каталог.</returns> public IEngineOperationsWithProgress<CatalogTree, EngineProgress> GetCatalog(BoardLinkBase link, UpdateCatalogMode mode = UpdateCatalogMode.Default) { var clink = Services.GetServiceOrThrow<ILinkTransformService>().GetCatalogLinkFromAnyLink(link) as BoardCatalogLink; if (clink == null) { throw new ArgumentException("Неправильный тип ссылки"); } if ((clink.LinkKind & BoardLinkKind.Catalog) == 0) { throw new ArgumentException("Неправильный тип ссылки"); } return new CatalogOperation(Services, new CatalogParameter() { Link = clink, UpdateMode = mode }); }
/// <summary> /// Загрузить список борд. /// </summary> /// <param name="rootLink">Корневая ссылка.</param> /// <param name="forceUpdate">Форсировать обновление.</param> /// <returns>Список борд (null - нет данных).</returns> public IEngineOperationsWithProgress<BoardReferences, EngineProgress> GetBoardReferences(BoardLinkBase rootLink, bool forceUpdate = false) { return new BoardReferenceOperation(Services, new BoardReferencesParameter() { RootLink = rootLink, ForceUpdate = forceUpdate }); }
/// <summary> /// Загрузить тред в архив. /// </summary> /// <param name="link">Ссылка.</param> /// <returns>Идентификатор архива.</returns> public IEngineOperationsWithProgress<Guid, EngineProgress> DownloadToArchive(BoardLinkBase link) { if ((link.LinkKind & BoardLinkKind.Thread) == 0) { throw new ArgumentException("Неправильный тип ссылки"); } return new DownloadArchiveOperation(Services, new DownloadArchiveOperationParameter() {Link = link}); }
/// <summary> /// Инициализирует новый экземпляр класса <see cref="T:System.EventArgs"/>. /// </summary> public BannerTappedEventArgs(BoardLinkBase link) { Link = link; }