├── docs ├── wordpressxf-v2-01.png └── wordpressxf-v2-02.png ├── WordPressXF ├── WordPressXF │ ├── WordPressXF │ │ ├── AssemblyInfo.cs │ │ ├── Assets │ │ │ └── account.png │ │ ├── Models │ │ │ └── NavigationTarget.cs │ │ ├── Styles │ │ │ ├── Colors.xaml.cs │ │ │ ├── Styles.xaml.cs │ │ │ ├── Colors.xaml │ │ │ └── Styles.xaml │ │ ├── ViewModels │ │ │ ├── BaseViewModel.cs │ │ │ ├── LoadingViewModel.cs │ │ │ ├── AccountViewModel.cs │ │ │ └── PostsViewModel.cs │ │ ├── Views │ │ │ ├── Controls │ │ │ │ ├── PostCommentView.xaml.cs │ │ │ │ ├── PostDetailView.xaml.cs │ │ │ │ ├── PostDetailOverviewPage.xaml.cs │ │ │ │ ├── CommentView.xaml │ │ │ │ ├── PostDetailView.xaml │ │ │ │ ├── CommentView.xaml.cs │ │ │ │ ├── ExternalWebView.cs │ │ │ │ ├── PostView.xaml │ │ │ │ ├── PostCommentView.xaml │ │ │ │ └── PostView.xaml.cs │ │ │ ├── AccountPage.xaml.cs │ │ │ ├── PostsOverviewPage.xaml.cs │ │ │ ├── LoadingPage.xaml │ │ │ ├── LoadingPage.xaml.cs │ │ │ ├── PostDetailOverviewPage.xaml │ │ │ ├── PostsOverviewPage.xaml │ │ │ └── AccountPage.xaml │ │ ├── Common │ │ │ ├── EnumerableExtensions.cs │ │ │ ├── Statics.cs │ │ │ └── HtmlTools.cs │ │ ├── Init │ │ │ ├── ViewModelLocator.cs │ │ │ └── Bootstrapper.cs │ │ ├── Services │ │ │ ├── SettingsService.cs │ │ │ ├── DialogService.cs │ │ │ ├── WordPressService.cs │ │ │ └── NavigationService.cs │ │ ├── Converters │ │ │ ├── NullToIsVisibleConverter.cs │ │ │ ├── HtmlStringToDecodedStringConverter.cs │ │ │ ├── HtmlStringToHtmlWebViewSourceConverter.cs │ │ │ ├── EmbeddedToFeaturedImageConverter.cs │ │ │ └── NameToInitialsConverter.cs │ │ ├── App.xaml.cs │ │ ├── App.xaml │ │ ├── WordPressXF.csproj │ │ └── Resources │ │ │ ├── AppResources.resx │ │ │ └── AppResources.Designer.cs │ ├── WordPressXF.iOS │ │ ├── Resources │ │ │ ├── splash.png │ │ │ ├── Default.png │ │ │ ├── Default@2x.png │ │ │ ├── Default-568h@2x.png │ │ │ ├── Default-Portrait.png │ │ │ ├── Default-Portrait@2x.png │ │ │ └── LaunchScreen.storyboard │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── AppIcon-120.png │ │ │ │ ├── AppIcon-152.png │ │ │ │ ├── AppIcon-167.png │ │ │ │ ├── AppIcon-180.png │ │ │ │ ├── AppIcon-20.png │ │ │ │ ├── AppIcon-29.png │ │ │ │ ├── AppIcon-40.png │ │ │ │ ├── AppIcon-401.png │ │ │ │ ├── AppIcon-402.png │ │ │ │ ├── AppIcon-58.png │ │ │ │ ├── AppIcon-581.png │ │ │ │ ├── AppIcon-60.png │ │ │ │ ├── AppIcon-76.png │ │ │ │ ├── AppIcon-80.png │ │ │ │ ├── AppIcon-801.png │ │ │ │ ├── AppIcon-87.png │ │ │ │ ├── AppIcon-1024.png │ │ │ │ ├── AppIcon-1201.png │ │ │ │ └── Contents.json │ │ ├── Entitlements.plist │ │ ├── Main.cs │ │ ├── AppDelegate.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Info.plist │ │ └── WordPressXF.iOS.csproj │ └── WordPressXF.Android │ │ ├── Resources │ │ ├── mipmap-hdpi │ │ │ ├── appicon.png │ │ │ ├── appiconround.png │ │ │ ├── appicon_background.png │ │ │ ├── appicon_foreground.png │ │ │ ├── launcher_foreground.png │ │ │ ├── appiconround_background.png │ │ │ └── appiconround_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── appicon.png │ │ │ ├── appiconround.png │ │ │ ├── appicon_background.png │ │ │ ├── appicon_foreground.png │ │ │ ├── launcher_foreground.png │ │ │ ├── appiconround_background.png │ │ │ └── appiconround_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── appicon.png │ │ │ ├── appiconround.png │ │ │ ├── appicon_background.png │ │ │ ├── appicon_foreground.png │ │ │ ├── launcher_foreground.png │ │ │ ├── appiconround_background.png │ │ │ └── appiconround_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── appicon.png │ │ │ ├── appiconround.png │ │ │ ├── appicon_background.png │ │ │ ├── appicon_foreground.png │ │ │ ├── launcher_foreground.png │ │ │ ├── appiconround_background.png │ │ │ └── appiconround_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── appicon.png │ │ │ ├── appiconround.png │ │ │ ├── appicon_background.png │ │ │ ├── appicon_foreground.png │ │ │ ├── launcher_foreground.png │ │ │ ├── appiconround_background.png │ │ │ └── appiconround_foreground.png │ │ ├── drawable │ │ │ ├── splashscreenlogo.png │ │ │ └── splashscreen.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── appicon.xml │ │ │ └── appiconround.xml │ │ ├── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ └── AboutResources.txt │ │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ │ ├── SplashActivity.cs │ │ ├── Assets │ │ └── AboutAssets.txt │ │ ├── MainActivity.cs │ │ └── WordPressXF.Android.csproj └── WordPressXF.sln ├── LICENSE ├── README.md └── .gitignore /docs/wordpressxf-v2-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/docs/wordpressxf-v2-01.png -------------------------------------------------------------------------------- /docs/wordpressxf-v2-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/docs/wordpressxf-v2-02.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms.Xaml; 2 | 3 | [assembly: XamlCompilation(XamlCompilationOptions.Compile)] -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Assets/account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF/Assets/account.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Resources/splash.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default@2x.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default-568h@2x.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default-Portrait.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Resources/Default-Portrait@2x.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appicon.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appicon.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appicon.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appicon.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appicon.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/drawable/splashscreenlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/drawable/splashscreenlogo.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appiconround.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appiconround.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appiconround.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appiconround.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appiconround.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appiconround.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appiconround.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appiconround.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appiconround.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appiconround.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appicon_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appicon_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appicon_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appicon_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/launcher_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/launcher_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appicon_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appicon_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appicon_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appicon_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-120.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-152.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-167.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-180.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-20.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-40.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-401.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-401.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-402.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-402.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-58.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-581.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-581.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-60.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-76.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-80.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-801.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-801.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-87.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appiconround_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appiconround_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appiconround_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-hdpi/appiconround_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appiconround_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appiconround_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appiconround_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-mdpi/appiconround_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appicon_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appicon_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-1201.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-1201.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appiconround_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appiconround_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appiconround_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xhdpi/appiconround_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appiconround_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appiconround_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appiconround_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxhdpi/appiconround_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appiconround_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appiconround_background.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appiconround_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wp-net/WordPressXF-V2/main/WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-xxxhdpi/appiconround_foreground.png -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Models/NavigationTarget.cs: -------------------------------------------------------------------------------- 1 | namespace WordPressXF.Models 2 | { 3 | internal enum NavigationTarget 4 | { 5 | LoadingPage, 6 | AccountPage, 7 | PostsOverviewPage, 8 | PostDetailOverviewPage 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-anydpi-v26/appicon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #3F51B5 5 | #303F9F 6 | #FF4081 7 | 8 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/mipmap-anydpi-v26/appiconround.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Styles/Colors.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace WordPressXF.Styles 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class Colors : ResourceDictionary 8 | { 9 | public Colors() 10 | { 11 | InitializeComponent(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Styles/Styles.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace WordPressXF.Styles 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class Styles : ResourceDictionary 8 | { 9 | public Styles() 10 | { 11 | InitializeComponent(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/ViewModels/BaseViewModel.cs: -------------------------------------------------------------------------------- 1 | using CommunityToolkit.Mvvm.ComponentModel; 2 | 3 | namespace WordPressXF.ViewModels 4 | { 5 | [INotifyPropertyChanged] 6 | internal partial class BaseViewModel 7 | { 8 | [ObservableProperty] 9 | private bool _isLoading; 10 | 11 | [ObservableProperty] 12 | private bool _isRefreshing; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/PostCommentView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace WordPressXF.Views.Controls 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class PostCommentView : ContentView 8 | { 9 | public PostCommentView() 10 | { 11 | InitializeComponent(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/PostDetailView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace WordPressXF.Views.Controls 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class PostDetailView : ContentView 8 | { 9 | public PostDetailView() 10 | { 11 | InitializeComponent(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Common/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace WordPressXF.Common 4 | { 5 | internal static class EnumerableExtensions 6 | { 7 | public static void AddRange(this IList list, IEnumerable collection) 8 | { 9 | foreach (var item in collection) 10 | list.Add(item); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/PostDetailOverviewPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace WordPressXF.Views 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class PostDetailOverviewPage : ContentPage 8 | { 9 | public PostDetailOverviewPage() 10 | { 11 | InitializeComponent(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Common/Statics.cs: -------------------------------------------------------------------------------- 1 | namespace WordPressXF.Common 2 | { 3 | internal static class Statics 4 | { 5 | public static string WordpressUrl = "https://wordpress.org/news/wp-json/"; 6 | 7 | public static int PageSize = 10; 8 | 9 | public static string UsernameSettingsKey = "UsernameSettings"; 10 | public static string PasswordSettingsKey = "PasswordSettings"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/drawable/splashscreen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/AccountPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace WordPressXF.Views 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class AccountPage : ContentPage 14 | { 15 | public AccountPage() 16 | { 17 | InitializeComponent(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/PostsOverviewPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace WordPressXF.Views 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class PostsOverviewPage : ContentPage 14 | { 15 | public PostsOverviewPage() 16 | { 17 | InitializeComponent(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace WordPressXF.iOS 9 | { 10 | public class Application 11 | { 12 | // This is the main entry point of the application. 13 | static void Main(string[] args) 14 | { 15 | // if you want to use a different Application Delegate class from "AppDelegate" 16 | // you can specify it here. 17 | UIApplication.Main(args, null, typeof(AppDelegate)); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/LoadingPage.xaml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Init/ViewModelLocator.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using WordPressXF.ViewModels; 3 | 4 | namespace WordPressXF.Init 5 | { 6 | internal class ViewModelLocator 7 | { 8 | public AccountViewModel AccountViewModel 9 | => Bootstrapper.ServiceProvider.GetService(); 10 | 11 | public LoadingViewModel LoadingViewModel 12 | => Bootstrapper.ServiceProvider.GetService(); 13 | 14 | public PostsViewModel PostsViewModel 15 | => Bootstrapper.ServiceProvider.GetService(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Services/SettingsService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Xamarin.Essentials; 3 | 4 | namespace WordPressXF.Services 5 | { 6 | internal class SettingsService 7 | { 8 | public async Task GetAsync(string key) 9 | { 10 | return await SecureStorage.GetAsync(key); 11 | } 12 | 13 | public async Task SetAsync(string key, string value) 14 | { 15 | await SecureStorage.SetAsync(key, value); 16 | } 17 | 18 | public void Remove(string key) 19 | { 20 | SecureStorage.Remove(key); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/SplashActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.OS; 3 | using Android.Views; 4 | 5 | namespace WordPressXF.Droid 6 | { 7 | [Activity(Label = "WordPressXF", Icon = "@mipmap/appicon", RoundIcon = "@mipmap/appiconround", Theme = "@style/Theme.Splash", MainLauncher = true)] 8 | public class SplashActivity : Activity 9 | { 10 | protected override void OnCreate(Bundle savedInstanceState) 11 | { 12 | base.OnCreate(savedInstanceState); 13 | 14 | Window.SetStatusBarColor(Android.Graphics.Color.ParseColor("#004d40")); 15 | 16 | StartActivity(typeof(MainActivity)); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Services/DialogService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Xamarin.Forms; 3 | 4 | namespace WordPressXF.Services 5 | { 6 | internal class DialogService 7 | { 8 | public async Task OpenSimplePlatformDialogAsync(string title, string message, string accept) 9 | { 10 | await Application.Current?.MainPage?.DisplayAlert(title, message, accept); 11 | } 12 | 13 | public async Task OpenSimplePlatformDialogAsync(string title, string message, string accept, string cancel) 14 | { 15 | return await Application.Current?.MainPage?.DisplayAlert(title, message, accept, cancel); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Converters/NullToIsVisibleConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Xamarin.Forms; 4 | 5 | namespace WordPressXF.Converters 6 | { 7 | internal class NullToIsVisibleConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | if (parameter == null) 12 | return value == null; 13 | 14 | return value != null; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 18 | { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/LoadingPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using WordPressXF.ViewModels; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace WordPressXF.Views 6 | { 7 | [XamlCompilation(XamlCompilationOptions.Compile)] 8 | public partial class LoadingPage : ContentPage 9 | { 10 | private readonly LoadingViewModel _viewModel; 11 | 12 | public LoadingPage() 13 | { 14 | InitializeComponent(); 15 | 16 | _viewModel = (LoadingViewModel)BindingContext; 17 | } 18 | 19 | protected override async void OnAppearing() 20 | { 21 | base.OnAppearing(); 22 | 23 | await _viewModel.InitCommand.ExecuteAsync(null); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Converters/HtmlStringToDecodedStringConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Net; 4 | using WordPressXF.Common; 5 | using Xamarin.Forms; 6 | 7 | namespace WordPressXF.Converters 8 | { 9 | internal class HtmlStringToDecodedStringConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (value is not string valueString) 14 | return string.Empty; 15 | 16 | return HtmlTools.Strip(WebUtility.HtmlDecode(valueString)); 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/CommentView.xaml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Styles/Colors.xaml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | #004d40 7 | 8 | #004d40 9 | #FFFFFF 10 | 11 | #004d40 12 | #FFFFFF 13 | #D3D3D3 14 | #FFFFFF 15 | 16 | #004d40 17 | #FFFFFF 18 | 19 | #E0E0E0 20 | 21 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Converters/HtmlStringToHtmlWebViewSourceConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using WordPressPCL.Models; 4 | using WordPressXF.Common; 5 | using Xamarin.Forms; 6 | 7 | namespace WordPressXF.Converters 8 | { 9 | internal class HtmlStringToHtmlWebViewSourceConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (value is Post post) 14 | { 15 | var htmlContent = HtmlTools.CreateHtmlFromPost(post); 16 | return new HtmlWebViewSource { Html = htmlContent }; 17 | } 18 | 19 | return string.Empty; 20 | } 21 | 22 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 23 | { 24 | throw new NotImplementedException(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/PostDetailView.xaml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using WordPressXF.Init; 3 | using WordPressXF.Resources; 4 | using WordPressXF.Services; 5 | using WordPressXF.Views; 6 | using Xamarin.CommunityToolkit.Helpers; 7 | using Xamarin.Forms; 8 | 9 | namespace WordPressXF 10 | { 11 | public partial class App : Application 12 | { 13 | public App() 14 | { 15 | Bootstrapper.Init(); 16 | 17 | InitializeComponent(); 18 | 19 | LocalizationResourceManager.Current.Init(AppResources.ResourceManager); 20 | 21 | MainPage = new NavigationPage(new LoadingPage()); 22 | Bootstrapper.ServiceProvider.GetService().Initialize(MainPage); 23 | } 24 | 25 | protected override void OnStart() 26 | { 27 | } 28 | 29 | protected override void OnSleep() 30 | { 31 | } 32 | 33 | protected override void OnResume() 34 | { 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Converters/EmbeddedToFeaturedImageConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using WordPressPCL.Models; 6 | using Xamarin.Forms; 7 | 8 | namespace WordPressXF.Converters 9 | { 10 | internal class EmbeddedToFeaturedImageConverter : IValueConverter 11 | { 12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 13 | { 14 | if (value is not Embedded embedded) 15 | return string.Empty; 16 | 17 | if (embedded.WpFeaturedmedia == null) 18 | return string.Empty; 19 | 20 | var mediaList = new List(embedded.WpFeaturedmedia); 21 | return mediaList.Any() ? mediaList.First().SourceUrl : string.Empty; 22 | } 23 | 24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/CommentView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace WordPressXF.Views.Controls 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class CommentView : ContentView 8 | { 9 | public static readonly BindableProperty CommentProperty = 10 | BindableProperty.Create(nameof(Comment), typeof(string), typeof(CommentView)); 11 | 12 | public string Comment 13 | { 14 | get => (string)GetValue(CommentProperty); 15 | set => SetValue(CommentProperty, value); 16 | } 17 | 18 | public static readonly BindableProperty AuthorProperty = 19 | BindableProperty.Create(nameof(Author), typeof(string), typeof(CommentView)); 20 | 21 | public string Author 22 | { 23 | get => (string)GetValue(AuthorProperty); 24 | set => SetValue(AuthorProperty, value); 25 | } 26 | 27 | public CommentView() 28 | { 29 | InitializeComponent(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 WordPress.NET 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 24 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/App.xaml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/PostDetailOverviewPage.xaml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Converters/NameToInitialsConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Text; 5 | using Xamarin.Forms; 6 | 7 | namespace WordPressXF.Converters 8 | { 9 | internal class NameToInitialsConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (value is not string name) 14 | return string.Empty; 15 | 16 | if (string.IsNullOrEmpty(name)) 17 | return string.Empty; 18 | 19 | var words = name.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 20 | if (words.Length == 1) 21 | return words[0][0].ToString(); 22 | 23 | if (words.Length > 1) 24 | return words[0][0].ToString() + words[words.Length - 1][0].ToString(); 25 | 26 | return string.Empty; 27 | } 28 | 29 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using UIKit; 3 | 4 | namespace WordPressXF.iOS 5 | { 6 | // The UIApplicationDelegate for the application. This class is responsible for launching the 7 | // User Interface of the application, as well as listening (and optionally responding) to 8 | // application events from iOS. 9 | [Register("AppDelegate")] 10 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 11 | { 12 | // 13 | // This method is invoked when the application has loaded and is ready to run. In this 14 | // method you should instantiate the window, load the UI into it and then make the window 15 | // visible. 16 | // 17 | // You have 17 seconds to return from this method, or iOS will terminate your application. 18 | // 19 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 20 | { 21 | global::Xamarin.Forms.Forms.Init(); 22 | Xamarin.Forms.FormsMaterial.Init(); 23 | 24 | LoadApplication(new App()); 25 | 26 | return base.FinishedLaunching(app, options); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("WordPressXF.Android")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("WordPressXF.Android")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | [assembly: AssemblyVersion("1.0.0.0")] 26 | [assembly: AssemblyFileVersion("1.0.0.0")] 27 | 28 | // Add some common permissions, these can be removed if not needed 29 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)] 30 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] 31 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/ExternalWebView.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Essentials; 2 | using Xamarin.Forms; 3 | 4 | namespace WordPressXF.Views.Controls 5 | { 6 | internal class ExternalWebView : WebView 7 | { 8 | public ExternalWebView() 9 | { 10 | Navigating += ExternalWebViewOnNavigating; 11 | } 12 | 13 | private async void ExternalWebViewOnNavigating(object sender, WebNavigatingEventArgs e) 14 | { 15 | // check that Url is available 16 | if (e == null || string.IsNullOrEmpty(e.Url)) 17 | return; 18 | 19 | // check if URL doesn't start with http or https 20 | if (!e.Url.StartsWith("http") || !e.Url.StartsWith("https")) 21 | return; 22 | 23 | // check for youtube link 24 | if (e.Url.StartsWith("https://www.youtube.com/")) 25 | return; 26 | 27 | // check for twitter link 28 | if (e.Url.StartsWith("https://syndication.twitter.com/") || e.Url.StartsWith("https://platform.twitter.com")) 29 | return; 30 | 31 | // cancel WebView navigation 32 | e.Cancel = true; 33 | 34 | // open external browser to show website 35 | await Browser.OpenAsync(e.Url, BrowserLaunchMode.SystemPreferred); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | using Android.Runtime; 5 | 6 | namespace WordPressXF.Droid 7 | { 8 | [Activity(Theme = "@style/MainTheme", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)] 9 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 10 | { 11 | protected override void OnCreate(Bundle savedInstanceState) 12 | { 13 | base.OnCreate(savedInstanceState); 14 | 15 | Window.SetStatusBarColor(Android.Graphics.Color.ParseColor("#004d40")); 16 | 17 | Xamarin.Essentials.Platform.Init(this, savedInstanceState); 18 | global::Xamarin.Forms.Forms.Init(this, savedInstanceState); 19 | Xamarin.Forms.FormsMaterial.Init(this, savedInstanceState); 20 | 21 | LoadApplication(new App()); 22 | } 23 | 24 | public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) 25 | { 26 | Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); 27 | 28 | base.OnRequestPermissionsResult(requestCode, permissions, grantResults); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WordPressXF.iOS")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WordPressXF.iOS")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/PostView.xaml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 12 | 13 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIDeviceFamily 6 | 7 | 1 8 | 9 | UISupportedInterfaceOrientations 10 | 11 | UIInterfaceOrientationPortrait 12 | UIInterfaceOrientationLandscapeLeft 13 | UIInterfaceOrientationLandscapeRight 14 | 15 | UISupportedInterfaceOrientations~ipad 16 | 17 | UIInterfaceOrientationPortrait 18 | UIInterfaceOrientationPortraitUpsideDown 19 | UIInterfaceOrientationLandscapeLeft 20 | UIInterfaceOrientationLandscapeRight 21 | 22 | MinimumOSVersion 23 | 8.0 24 | CFBundleDisplayName 25 | WordPressXF 26 | CFBundleIdentifier 27 | com.companyname.WordPressXF 28 | CFBundleVersion 29 | 1.0 30 | UILaunchStoryboardName 31 | LaunchScreen 32 | UIStatusBarStyle 33 | UIStatusBarStyleLightContent 34 | UIViewControllerBasedStatusBarAppearance 35 | 36 | CFBundleName 37 | WordPressXF 38 | XSAppIconAssets 39 | Assets.xcassets/AppIcon.appiconset 40 | UIApplicationSceneManifest 41 | 42 | UIApplicationSupportsMultipleScenes 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/ViewModels/LoadingViewModel.cs: -------------------------------------------------------------------------------- 1 | using CommunityToolkit.Mvvm.ComponentModel; 2 | using CommunityToolkit.Mvvm.Input; 3 | using System; 4 | using System.Diagnostics; 5 | using System.Threading.Tasks; 6 | using WordPressXF.Models; 7 | using WordPressXF.Services; 8 | 9 | namespace WordPressXF.ViewModels 10 | { 11 | internal partial class LoadingViewModel : BaseViewModel 12 | { 13 | private readonly NavigationService _navigationService; 14 | private readonly AccountViewModel _accountViewModel; 15 | private readonly PostsViewModel _postsViewModel; 16 | 17 | 18 | public LoadingViewModel(NavigationService navigationService, AccountViewModel accountViewModel, PostsViewModel postsViewModel) 19 | { 20 | _navigationService = navigationService; 21 | _accountViewModel = accountViewModel; 22 | _postsViewModel = postsViewModel; 23 | } 24 | 25 | 26 | [ICommand(AllowConcurrentExecutions = false)] 27 | private async Task InitAsync() 28 | { 29 | IsLoading = true; 30 | 31 | try 32 | { 33 | await _accountViewModel.TryAutoLoginCommand.ExecuteAsync(null); 34 | await _postsViewModel.LoadPostsCommand.ExecuteAsync(null); 35 | 36 | await _navigationService.NavigateToAsync(NavigationTarget.PostsOverviewPage); 37 | _navigationService.ClearBackstack(); 38 | } 39 | catch (Exception ex) 40 | { 41 | Debug.WriteLine($"{nameof(LoadingViewModel)} | {nameof(InitAsync)} | {ex}"); 42 | } 43 | finally 44 | { 45 | IsLoading = false; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WordPressXF - V2 2 | This is a Xamarin.Forms app (supporting Android and iOS) designed to turn easily WordPress Blogs / Sites into nice little apps. 3 | 4 | It's built on 5 | * [WordPressPCL (WordPress REST API Wrapper)](https://github.com/wp-net/WordPressPCL) 6 | * [Xamarin.Forms 5.0](https://github.com/xamarin/Xamarin.Forms) 7 | 8 | 9 | ## Features 10 | 11 | working and planned features for WordPressXF: 12 | - [x] Show posts 13 | - [x] Show comments 14 | - [x] Custom app icons 15 | - [x] Use SplashScreen 16 | - [x] Sign In 17 | - [x] Add comment 18 | 19 | 20 | ## Screenshots 21 | 22 | Screenshot-01 23 | 24 |
25 | 26 | Screenshot-02 27 | 28 | 29 | # Quickstart 30 | 31 | ## WordPress Plugins 32 | 33 | Since WordPress 4.7 the REST API has been integrated into the core so there's no need for any plugins to get basic functionality. If you want to access protected endpoints, this library supports authentication through JSON Web Tokens (JWT) (plugin required). 34 | 35 | * [WordPress 4.7 or newer](https://wordpress.org/) 36 | * [JWT Authentication for WP REST API](https://wordpress.org/plugins/jwt-authentication-for-wp-rest-api/) 37 | 38 | 39 | ## Getting Started 40 | 41 | Just clone or download the repo and open it in Visual Studio. Before you can build you'll need to enter the URL to your WordPress blog/site in the file [WordPressXF/WordPressXF/WordPressXF/Common/Statics.cs](https://github.com/wp-net/WordPressXF-V2/blob/main/WordPressXF/WordPressXF/WordPressXF/Common/Statics.cs). And don't forget to add `/wp-json/` at the end. 42 | 43 | ```c# 44 | namespace WordPressXF.Common 45 | { 46 | public static class Statics 47 | { 48 | public static string WordpressUrl = "https://wordpress.org/news/wp-json/"; 49 | 50 | // other properties 51 | } 52 | } 53 | ``` 54 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF.Android/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable-hdpi/ 12 | icon.png 13 | 14 | drawable-ldpi/ 15 | icon.png 16 | 17 | drawable-mdpi/ 18 | icon.png 19 | 20 | layout/ 21 | main.xml 22 | 23 | values/ 24 | strings.xml 25 | 26 | In order to get the build system to recognize Android resources, set the build action to 27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 28 | instead operate on resource IDs. When you compile an Android application that uses resources, 29 | the build system will package the resources for distribution and generate a class called 30 | "Resource" that contains the tokens for each one of the resources included. For example, 31 | for the above Resources layout, this is what the Resource class would expose: 32 | 33 | public class Resource { 34 | public class drawable { 35 | public const int icon = 0x123; 36 | } 37 | 38 | public class layout { 39 | public const int main = 0x456; 40 | } 41 | 42 | public class strings { 43 | public const int first_string = 0xabc; 44 | public const int second_string = 0xbcd; 45 | } 46 | } 47 | 48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main 49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first 50 | string in the dictionary file values/strings.xml. 51 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/PostsOverviewPage.xaml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 19 | 22 | 23 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /WordPressXF/WordPressXF/WordPressXF/Views/Controls/PostCommentView.xaml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 14 | 15 | 17 | 18 | 19 | 21 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 31 | 34 |