diff --git a/PlexConnectApp.xcodeproj/project.pbxproj b/PlexConnectApp.xcodeproj/project.pbxproj
index 05c706c..e5b0a40 100644
--- a/PlexConnectApp.xcodeproj/project.pbxproj
+++ b/PlexConnectApp.xcodeproj/project.pbxproj
@@ -130,6 +130,7 @@
TargetAttributes = {
01CE20651BE6ADD500A2F10A = {
CreatedOnToolsVersion = 7.1;
+ DevelopmentTeam = TAQDRE37FL;
};
};
};
@@ -284,11 +285,14 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer";
INFOPLIST_FILE = PlexConnectApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = "-.PlexConnectApp";
+ PRODUCT_BUNDLE_IDENTIFIER = PlexRevenant;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TVOS_DEPLOYMENT_TARGET = 9.2;
};
name = Debug;
};
@@ -299,10 +303,13 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer";
INFOPLIST_FILE = PlexConnectApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = "-.PlexConnectApp";
+ PRODUCT_BUNDLE_IDENTIFIER = PlexRevenant;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ TVOS_DEPLOYMENT_TARGET = 9.2;
};
name = Release;
};
diff --git a/PlexConnectApp.xcodeproj/project.xcworkspace/xcuserdata/CyberGhost.xcuserdatad/UserInterfaceState.xcuserstate b/PlexConnectApp.xcodeproj/project.xcworkspace/xcuserdata/CyberGhost.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..f62be17
Binary files /dev/null and b/PlexConnectApp.xcodeproj/project.xcworkspace/xcuserdata/CyberGhost.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/PlexConnectApp.xcodeproj/xcuserdata/CyberGhost.xcuserdatad/xcschemes/PlexConnectApp.xcscheme b/PlexConnectApp.xcodeproj/xcuserdata/CyberGhost.xcuserdatad/xcschemes/PlexConnectApp.xcscheme
new file mode 100644
index 0000000..b74f332
--- /dev/null
+++ b/PlexConnectApp.xcodeproj/xcuserdata/CyberGhost.xcuserdatad/xcschemes/PlexConnectApp.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PlexConnectApp.xcodeproj/xcuserdata/CyberGhost.xcuserdatad/xcschemes/xcschememanagement.plist b/PlexConnectApp.xcodeproj/xcuserdata/CyberGhost.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..b3eb03c
--- /dev/null
+++ b/PlexConnectApp.xcodeproj/xcuserdata/CyberGhost.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ SchemeUserState
+
+ PlexConnectApp.xcscheme
+
+ orderHint
+ 0
+
+
+ SuppressBuildableAutocreation
+
+ 01CE20651BE6ADD500A2F10A
+
+ primary
+
+
+
+
+
diff --git a/PlexConnectApp/AppDelegate.swift b/PlexConnectApp/AppDelegate.swift
old mode 100644
new mode 100755
index 66960d9..4364200
--- a/PlexConnectApp/AppDelegate.swift
+++ b/PlexConnectApp/AppDelegate.swift
@@ -63,6 +63,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, TVApplicationControllerDe
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+
print("WillResignActive")
}
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Background 1280x768.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Background 1280x768.png
deleted file mode 100644
index 125c335..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Background 1280x768.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Background.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Background.png
new file mode 100755
index 0000000..1143a87
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Background.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index ca6d1a9..a51e80e
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "Background 1280x768.png",
+ "filename" : "Background.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/Boy 1280x768.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/Boy 1280x768.png
deleted file mode 100644
index bd3ce3d..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/Boy 1280x768.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index 5a50320..63e1d2e
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "Boy 1280x768.png",
+ "filename" : "connect.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/connect.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/connect.png
new file mode 100755
index 0000000..776aaea
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Content.imageset/connect.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Boy.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index 4df00aa..7be52c2
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "Empty 1280x768.png",
+ "filename" : "Empty 400x240.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Empty 1280x768.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Empty 1280x768.png
deleted file mode 100644
index 29e0073..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Empty 1280x768.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Empty 400x240.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Empty 400x240.png
new file mode 100755
index 0000000..5ad839d
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Content.imageset/Empty 400x240.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Empty.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index d811e32..7be52c2
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "Girl 1280x768.png",
+ "filename" : "Empty 400x240.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Empty 400x240.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Empty 400x240.png
new file mode 100755
index 0000000..5ad839d
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Empty 400x240.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Girl 1280x768.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Girl 1280x768.png
deleted file mode 100644
index 504cedd..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Content.imageset/Girl 1280x768.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Girl.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index 43c077d..5392b7d
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "TVSet 1280x768.png",
+ "filename" : "Plex.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/Plex.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/Plex.png
new file mode 100755
index 0000000..1ed11f0
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/Plex.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/TVSet 1280x768.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/TVSet 1280x768.png
deleted file mode 100644
index 69d56c6..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Content.imageset/TVSet 1280x768.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/TVSet.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Background 400x240.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Background 400x240.png
deleted file mode 100644
index a7b08c2..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Background 400x240.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Background-small.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Background-small.png
new file mode 100755
index 0000000..d09903b
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Background-small.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index f00a298..5d9291d
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "Background 400x240.png",
+ "filename" : "Background-small.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/Boy 400x240.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/Boy 400x240.png
deleted file mode 100644
index ba7a56b..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/Boy 400x240.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index 48460f3..26040ef
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "Boy 400x240.png",
+ "filename" : "connect-small.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/connect-small.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/connect-small.png
new file mode 100755
index 0000000..764640e
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Content.imageset/connect-small.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Boy.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Empty.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Empty.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Empty.imagestacklayer/Content.imageset/Empty 400x240.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Empty.imagestacklayer/Content.imageset/Empty 400x240.png
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Empty.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Empty.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index 49394ea..7be52c2
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "Girl 400x240.png",
+ "filename" : "Empty 400x240.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Empty 400x240.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Empty 400x240.png
new file mode 100755
index 0000000..5ad839d
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Empty 400x240.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Girl 400x240.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Girl 400x240.png
deleted file mode 100644
index 4d8546a..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Content.imageset/Girl 400x240.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Girl.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/Contents.json
old mode 100644
new mode 100755
index 0f3b672..08b00c6
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "TVSet 400x240.png",
+ "filename" : "Plex-small.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/Plex-small.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/Plex-small.png
new file mode 100755
index 0000000..cb7596f
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/Plex-small.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/TVSet 400x240.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/TVSet 400x240.png
deleted file mode 100644
index 3a06855..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Content.imageset/TVSet 400x240.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/TVSet.imagestacklayer/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
old mode 100644
new mode 100755
index 780e4a4..3eed833
--- a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "tv",
- "filename" : "TopShelf 1920x720.png",
+ "filename" : "LaunchImage2.png",
"scale" : "1x"
}
],
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/LaunchImage2.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/LaunchImage2.png
new file mode 100755
index 0000000..4506df4
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/LaunchImage2.png differ
diff --git a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/TopShelf 1920x720.png b/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/TopShelf 1920x720.png
deleted file mode 100644
index 6c24c55..0000000
Binary files a/PlexConnectApp/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/TopShelf 1920x720.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/Contents.json b/PlexConnectApp/Assets.xcassets/Contents.json
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/Contents.json b/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/Contents.json
old mode 100644
new mode 100755
index 54e8c0e..93e7c5f
--- a/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/Contents.json
+++ b/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/Contents.json
@@ -3,7 +3,7 @@
{
"orientation" : "landscape",
"idiom" : "tv",
- "filename" : "LaunchImage 1920x1080.png",
+ "filename" : "LaunchImage.png",
"extent" : "full-screen",
"minimum-system-version" : "9.0",
"scale" : "1x"
diff --git a/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/LaunchImage 1920x1080.png b/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/LaunchImage 1920x1080.png
deleted file mode 100644
index de06af8..0000000
Binary files a/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/LaunchImage 1920x1080.png and /dev/null differ
diff --git a/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/LaunchImage.png b/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/LaunchImage.png
new file mode 100755
index 0000000..96b39f5
Binary files /dev/null and b/PlexConnectApp/Assets.xcassets/LaunchImage.launchimage/LaunchImage.png differ
diff --git a/PlexConnectApp/Images/button-resume.png b/PlexConnectApp/Images/button-resume.png
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Images/folder.png b/PlexConnectApp/Images/folder.png
index 5ef13de..10e6e5d 100644
Binary files a/PlexConnectApp/Images/folder.png and b/PlexConnectApp/Images/folder.png differ
diff --git a/PlexConnectApp/Images/icon_cloud.png b/PlexConnectApp/Images/icon_cloud.png
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Images/icon_key.png b/PlexConnectApp/Images/icon_key.png
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Images/icon_lock.png b/PlexConnectApp/Images/icon_lock.png
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/Images/missing-image.png b/PlexConnectApp/Images/missing-image.png
index 89b129a..9dff492 100644
Binary files a/PlexConnectApp/Images/missing-image.png and b/PlexConnectApp/Images/missing-image.png differ
diff --git a/PlexConnectApp/Info.plist b/PlexConnectApp/Info.plist
index e289243..846d764 100644
--- a/PlexConnectApp/Info.plist
+++ b/PlexConnectApp/Info.plist
@@ -22,13 +22,13 @@
1
LSRequiresIPhoneOS
- UIMainStoryboardFile
- Main
NSAppTransportSecurity
NSAllowsArbitraryLoads
+ UIMainStoryboardFile
+ Main
UIRequiredDeviceCapabilities
arm64
diff --git a/PlexConnectApp/JsInterface.swift b/PlexConnectApp/JsInterface.swift
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/PlexAPI.swift b/PlexConnectApp/PlexAPI.swift
index b9b014a..19c91c3 100644
--- a/PlexConnectApp/PlexAPI.swift
+++ b/PlexConnectApp/PlexAPI.swift
@@ -20,13 +20,13 @@ var plexUserInformation = cPlexUserInformation()
class cPlexUserInformation {
private let _storage = NSUserDefaults.standardUserDefaults()
-
+
private var _attributes: [String: String] = [:]
-/*
- private var _name: String
- private var _email: String
- private var _token: String
- */
+ /*
+ private var _name: String
+ private var _email: String
+ private var _token: String
+ */
private var _xmlUser: XMLIndexer? // store for debugging - XML data this PMS was set up with
private var _xmlHomeUser: XMLIndexer?
@@ -35,7 +35,7 @@ class cPlexUserInformation {
_xmlUser = nil
_xmlHomeUser = nil
_attributes = ["adminname": "", "name": "", "email": "", "token": "", "id": ""]
-
+
if let name = _storage.stringForKey("adminname") {
_attributes["adminname"] = name
}
@@ -57,7 +57,7 @@ class cPlexUserInformation {
_xmlUser = xmlUser
_xmlHomeUser = nil
_attributes = ["adminname": "", "name": "", "email": "", "token": "", "id": ""]
-
+
// todo: check XML and neccessary nodes
if let name = xmlUser.element!.attributes["title"] {
_attributes["adminname"] = name
@@ -72,13 +72,13 @@ class cPlexUserInformation {
if let id = _storage.stringForKey("id") {
_attributes["id"] = id
}
-
+
store()
}
func switchHomeUser(xmlUser: XMLIndexer) {
_xmlHomeUser = xmlUser
-
+
if let name = xmlUser.element!.attributes["title"] {
_attributes["name"] = name
}
@@ -99,7 +99,7 @@ class cPlexUserInformation {
_xmlUser = nil
_xmlHomeUser = nil
_attributes = ["adminname": "", "name": "", "email": "", "token": "", "id": ""]
-
+
store()
}
@@ -145,13 +145,13 @@ class cPlexMediaServerInformation {
_fastestConnection = nil
let dsptch = dispatch_semaphore_create(0)
for (_ix,_con) in xmlPms["Connection"].enumerate() {
-
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let url = NSURL(string: _con.element!.attributes["uri"]! + "?X-Plex-Token=" + self._attributes["accessToken"]!)
let request = NSMutableURLRequest(URL: url!)
-
+
let task = session.dataTaskWithRequest(request) {
(data, response, error) -> Void in
if let httpResp = response as? NSHTTPURLResponse {
@@ -166,7 +166,7 @@ class cPlexMediaServerInformation {
})
}
dispatch_semaphore_wait(dsptch, dispatch_time(DISPATCH_TIME_NOW, httpTimeout)) // todo: 10sec timeout?
-
+
// add connection details of fastest response to top level _attributes
if let _ = _fastestConnection {
for (key, value) in xmlPms["Connection"][_fastestConnection!].element!.attributes {
@@ -204,7 +204,7 @@ func getPmsUrl(key: String, pmsId: String, pmsPath: String) -> String {
url = "https://plex.tv"
token = plexUserInformation.getAttribute("token")
}
-
+
// path
if (key.hasPrefix("/")) { // internal full path
url = url + key
@@ -213,7 +213,7 @@ func getPmsUrl(key: String, pmsId: String, pmsPath: String) -> String {
} else { // relative path - current plex new path component
url = url + pmsPath + "/" + key
}
-
+
// token
if token != "" {
var queryDelimiter = "?"
@@ -231,7 +231,7 @@ func getPmsUrl(key: String, pmsId: String, pmsPath: String) -> String {
func getVideoPath(video: XMLIndexer, partIx: Int, pmsId: String, pmsPath: String?) -> String {
var res: String
-
+
// sanity check: pmsId
var accessToken: String
var pmsUri: String
@@ -261,7 +261,7 @@ func getVideoPath(video: XMLIndexer, partIx: Int, pmsId: String, pmsPath: String
// XML pointing to Video node
let media = video["Media"][0] // todo: cover XMLError, errorchecking on optionals
let part = media["Part"][partIx]
-
+
// transcoder action
let transcoderAction = settings.getSetting("transcoderAction")
@@ -270,23 +270,23 @@ func getVideoPath(video: XMLIndexer, partIx: Int, pmsId: String, pmsPath: String
// or native aTV media
var videoATVNative =
["hls"].contains(getAttribute(media, key: "protocol", dflt: ""))
- ||
- ["mov", "mp4"].contains(getAttribute(media, key: "container", dflt: "")) &&
- ["mpeg4", "h264", "drmi"].contains(getAttribute(media, key: "videoCodec", dflt: "")) &&
- ["aac", "ac3", "drms"].contains(getAttribute(media, key: "audioCodec", dflt: ""))
-
+ ||
+ ["mov", "mp4"].contains(getAttribute(media, key: "container", dflt: "")) &&
+ ["mpeg4", "h264", "drmi"].contains(getAttribute(media, key: "videoCodec", dflt: "")) &&
+ ["aac", "ac3", "drms"].contains(getAttribute(media, key: "audioCodec", dflt: ""))
+
/* limitation of aTV2/3 only?
- for stream in part["Stream"] {
- if (stream.element!.attributes["streamType"] == "1" &&
- ["mpeg4", "h264"].contains(stream.element!.attributes["codec"]!)) {
- if (stream.element!.attributes["profile"] == "high 10" ||
- Int(stream.element!.attributes["refFrames"]!) > 8) {
- videoATVNative = false
- break
- }
- }
- }
- */
+ for stream in part["Stream"] {
+ if (stream.element!.attributes["streamType"] == "1" &&
+ ["mpeg4", "h264"].contains(stream.element!.attributes["codec"]!)) {
+ if (stream.element!.attributes["profile"] == "high 10" ||
+ Int(stream.element!.attributes["refFrames"]!) > 8) {
+ videoATVNative = false
+ break
+ }
+ }
+ }
+ */
print("videoATVNative: " + String(videoATVNative))
// quality limits: quality=(resolution, quality, bitrate)
@@ -314,36 +314,36 @@ func getVideoPath(video: XMLIndexer, partIx: Int, pmsId: String, pmsPath: String
// subtitle renderer, subtitle selection
/* not used yet - todo: implement and test
- let subtitleRenderer = settings.getSetting("subtitleRenderer")
-
- var subtitleId = ""
- var subtitleKey = ""
- var subtitleFormat = ""
- for stream in part["Stream"] { // todo: check 'Part' existance, deal with multi part video
- if stream.element!.attributes["streamType"] == "3" &&
- stream.element!.attributes["selected"] == "1" {
- subtitleId = stream.element!.attributes["id"]!
- subtitleKey = stream.element!.attributes["key"]!
- subtitleFormat = stream.element!.attributes["format"]!
- break
- }
- }
-
- let subtitleIOSNative = (subtitleKey == "") && (subtitleFormat == "tx3g") // embedded
- let subtitleThisApp = (subtitleKey != "") && (subtitleFormat == "srt") // external
-
- // subtitle suitable for direct play?
- // no subtitle
- // or 'Auto' with subtitle by iOS or ThisApp
- // or 'iOS,PMS' with subtitle by iOS
- let subtitleDirectPlay =
- subtitleId == ""
- ||
- subtitleRenderer == "Auto" && ( (videoATVNative && subtitleIOSNative) || subtitleThisApp )
- ||
- subtitleRenderer == "iOS, PMS" && (videoATVNative && subtitleIOSNative)
- print("subtitle: IOSNative - {0}, PlexConnect - {1}, DirectPlay - {2}", subtitleIOSNative, subtitleThisApp, subtitleDirectPlay)
- */
+ let subtitleRenderer = settings.getSetting("subtitleRenderer")
+
+ var subtitleId = ""
+ var subtitleKey = ""
+ var subtitleFormat = ""
+ for stream in part["Stream"] { // todo: check 'Part' existance, deal with multi part video
+ if stream.element!.attributes["streamType"] == "3" &&
+ stream.element!.attributes["selected"] == "1" {
+ subtitleId = stream.element!.attributes["id"]!
+ subtitleKey = stream.element!.attributes["key"]!
+ subtitleFormat = stream.element!.attributes["format"]!
+ break
+ }
+ }
+
+ let subtitleIOSNative = (subtitleKey == "") && (subtitleFormat == "tx3g") // embedded
+ let subtitleThisApp = (subtitleKey != "") && (subtitleFormat == "srt") // external
+
+ // subtitle suitable for direct play?
+ // no subtitle
+ // or 'Auto' with subtitle by iOS or ThisApp
+ // or 'iOS,PMS' with subtitle by iOS
+ let subtitleDirectPlay =
+ subtitleId == ""
+ ||
+ subtitleRenderer == "Auto" && ( (videoATVNative && subtitleIOSNative) || subtitleThisApp )
+ ||
+ subtitleRenderer == "iOS, PMS" && (videoATVNative && subtitleIOSNative)
+ print("subtitle: IOSNative - {0}, PlexConnect - {1}, DirectPlay - {2}", subtitleIOSNative, subtitleThisApp, subtitleDirectPlay)
+ */
// determine video URL
// direct play for...
@@ -356,11 +356,11 @@ func getVideoPath(video: XMLIndexer, partIx: Int, pmsId: String, pmsPath: String
let key = getAttribute(part, key: "key", dflt: "")
let indirect = getAttribute(media, key: "indirect", dflt: "0")
if indirect == "1" ||
- key.hasPrefix("http://") || key.hasPrefix("https://") {
+ key.hasPrefix("http://") || key.hasPrefix("https://") {
res = key
} else if transcoderAction == "DirectPlay"
- ||
- transcoderAction == "Auto" && videoATVNative && qualityDirectPlay /*&& subtitleDirectPlay*/ {
+ ||
+ transcoderAction == "Auto" && videoATVNative && qualityDirectPlay /*&& subtitleDirectPlay*/ {
// direct play
var xargs = getDeviceInfoXArgs()
if accessToken != "" {
@@ -378,18 +378,18 @@ func getVideoPath(video: XMLIndexer, partIx: Int, pmsId: String, pmsPath: String
// misc settings: subtitlesize, audioboost
/*
- let subtitle = ["selected": "1" if subtitleId else "0",
- "dontBurnIn": "1" if subtitleDirectPlay else "0",
- "size": settings.getSetting("subtitlesize") ]
- */
+ let subtitle = ["selected": "1" if subtitleId else "0",
+ "dontBurnIn": "1" if subtitleDirectPlay else "0",
+ "size": settings.getSetting("subtitlesize") ]
+ */
let audio = ["boost": "100" /*settings.getSetting("audioboost")*/ ]
let args = getTranscodeVideoArgs(key, ratingKey: ratingKey, partIx: partIx,
- transcoderAction: transcoderAction,
- quality: quality,
- audio: audio
+ transcoderAction: transcoderAction,
+ quality: quality,
+ audio: audio
// subtitle: subtitle
- )
+ )
var xargs = getDeviceInfoXArgs()
xargs += [
@@ -432,12 +432,12 @@ func getDirectVideoPath(key: String, pmsToken: String) -> String {
}
res = key + queryDelimiter + "X-Plex-Token=" + pmsToken // todo: does token need urlencode?
}
-
+
return res
}
func getTranscodeVideoArgs(path: String, ratingKey: String, partIx: Int, transcoderAction: String, quality: [String: String], audio: [String: String]) -> [NSURLQueryItem] {
-
+
var directStream: String
if transcoderAction == "Transcode" {
directStream = "0" // force transcoding, no direct stream
@@ -445,13 +445,13 @@ func getTranscodeVideoArgs(path: String, ratingKey: String, partIx: Int, transco
directStream = "1"
}
// transcoderAction 'directPlay' - handled by the client in MEDIARUL()
-
+
let args: [NSURLQueryItem] = [
NSURLQueryItem(name: "path", value: path),
NSURLQueryItem(name: "partIndex", value: String(partIx)),
NSURLQueryItem(name: "session", value: ratingKey), // todo: session UDID? ratingKey?
-
+
NSURLQueryItem(name: "protocol", value: "hls"),
NSURLQueryItem(name: "videoResolution", value: quality["resolution"]!),
NSURLQueryItem(name: "videoQuality", value: quality["quality"]!),
@@ -463,9 +463,9 @@ func getTranscodeVideoArgs(path: String, ratingKey: String, partIx: Int, transco
NSURLQueryItem(name: "skipSubtitles", value: "1"), // no PMS subtitles for now
/* todo: subtitle support
- args["subtitleSize"] = subtitle["size"]
- args["skipSubtitles"] = subtitle["dontBurnIn"] // '1' // shut off PMS subtitles. Todo: skip only for aTV native/SRT (or other supported)
- */
+ args["subtitleSize"] = subtitle["size"]
+ args["skipSubtitles"] = subtitle["dontBurnIn"] // '1' // shut off PMS subtitles. Todo: skip only for aTV native/SRT (or other supported)
+ */
]
return args
@@ -495,7 +495,7 @@ func getAudioPath(audio: XMLIndexer, partIx: Int, pmsId: String, pmsPath: String
quality["bitrate"] = "384" // maxAudioBitrate // todo: setting?
let qualityDirectPlay = Int(getAttribute(media, key: "bitrate", dflt: "0")) < Int(quality["bitrate"]!)
print("quality: ", quality["bitrate"], "qualityDirectPlay: ", qualityDirectPlay)
-
+
// determine adio URL
// direct play for...
// audioATVNative
@@ -541,7 +541,7 @@ func getAudioPath(audio: XMLIndexer, partIx: Int, pmsId: String, pmsPath: String
// internal path, add-on
res = PlexMediaServerInformation[pmsId]!.getAttribute("uri") + pmsPath! + "/" + res
}
-
+
return res
}
@@ -551,11 +551,11 @@ func getTranscodeAudioArgs(path: String, ratingKey: String, quality: [String: St
NSURLQueryItem(name: "path", value: path),
// mediaIndex
// partIndex
-
+
NSURLQueryItem(name: "session", value: ratingKey), // todo: session UDID? ratingKey?
NSURLQueryItem(name: "protocol", value: "http"),
NSURLQueryItem(name: "maxAudioBitrate", value: quality["bitrate"]!),
- ]
+ ]
return args
}
@@ -566,18 +566,18 @@ func getPhotoPath(photo: XMLIndexer, width: String, height: String, pmsId: Strin
// sanity check
// todo: ?
-
+
// XML pointing to Video node
let media = photo["Media"][0] // todo: cover XMLError, errorchecking on optionals
let part = media["Part"][0]
-
+
// todo: transcoder action setting
//let transcoderAction = settings.getSetting("transcoderAction")
-
+
// photo format
let photoATVNative = ["jpg","jpeg","tif","tiff","gif","png"].contains(getAttribute(media, key: "container", dflt: ""))
print("photoATVNative: " + String(photoATVNative))
-
+
let accessToken = PlexMediaServerInformation[pmsId]!.getAttribute("accessToken")
if photoATVNative && width=="" && height=="" {
// direct play
@@ -605,7 +605,7 @@ func getPhotoPath(photo: XMLIndexer, width: String, height: String, pmsId: Strin
_width = "1920"
_height = "1080"
}
-
+
var photoPath: String
if key.hasPrefix("/") {
// internal full path
@@ -617,12 +617,12 @@ func getPhotoPath(photo: XMLIndexer, width: String, height: String, pmsId: Strin
// internal path, add-on
photoPath = "http://127.0.0.1:32400" + pmsPath! + "/" + key
}
-
+
let args: [NSURLQueryItem] = [
NSURLQueryItem(name: "url", value: photoPath),
NSURLQueryItem(name: "width", value: _width),
NSURLQueryItem(name: "height", value: _height),
- ]
+ ]
var xargs: [NSURLQueryItem] = []
if accessToken != "" {
@@ -634,7 +634,7 @@ func getPhotoPath(photo: XMLIndexer, width: String, height: String, pmsId: Strin
res = urlComponents!.string!
}
-
+
if res.hasPrefix("/") {
// internal full path
res = PlexMediaServerInformation[pmsId]!.getAttribute("uri") + res
@@ -644,11 +644,11 @@ func getPhotoPath(photo: XMLIndexer, width: String, height: String, pmsId: Strin
// internal path, add-on
res = PlexMediaServerInformation[pmsId]!.getAttribute("uri") + pmsPath! + res
}
-
+
return res
}
-
+
func getDeviceInfoXArgs() -> [NSURLQueryItem] {
let device = UIDevice()
@@ -660,7 +660,7 @@ func getDeviceInfoXArgs() -> [NSURLQueryItem] {
NSURLQueryItem(name: "X-Plex-Platform", value: "iOS" /*device.systemName*/), // todo: have PMS to accept tvOS
NSURLQueryItem(name: "X-Plex-Client-Platform", value: "iOS" /*device.systemName*/),
NSURLQueryItem(name: "X-Plex-Platform-Version", value: device.systemVersion),
-
+
NSURLQueryItem(name: "X-Plex-Client-Identifier", value: device.identifierForVendor?.UUIDString),
NSURLQueryItem(name: "X-Plex-Product", value: "PlexConnectApp"), // todo: actual App name
@@ -701,7 +701,7 @@ func getXMLWait(url: String) -> XMLIndexer? {
let dsptch = dispatch_semaphore_create(0)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
-
+
let _nsurl = NSURL(string: url)
//let session = NSURLSession.sharedSession()
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
@@ -717,7 +717,7 @@ func getXMLWait(url: String) -> XMLIndexer? {
task.resume()
})
dispatch_semaphore_wait(dsptch, dispatch_time(DISPATCH_TIME_NOW, httpTimeout))
-
+
return XML
}
@@ -736,12 +736,12 @@ func myPlexSignIn(username: String, password: String) {
let url = NSURL(string: "https://plex.tv/users/sign_in.xml")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
-
+
let xargs = getDeviceInfoXArgs()
for xarg in xargs {
request.addValue(xarg.value!, forHTTPHeaderField: xarg.name)
}
-
+
print("signing in")
let dsptch = dispatch_semaphore_create(0)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
@@ -851,9 +851,9 @@ func myPlexSwitchHomeUser(id: String, pin: String) {
func discoverServers() {
// check for servers
let _url = "https://plex.tv/api/resources?includeHttps=1" +
- "&X-Plex-Token=" + plexUserInformation.getAttribute("token")
+ "&X-Plex-Token=" + plexUserInformation.getAttribute("token")
let _xml = getXMLWait(_url)
-
+
PlexMediaServerInformation = [:]
if (_xml != nil) && (_xml!["MediaContainer"] /*!=XMLError*/) {
var _pms: cPlexMediaServerInformation
@@ -864,4 +864,4 @@ func discoverServers() {
}
}
}
-}
+}
\ No newline at end of file
diff --git a/PlexConnectApp/Settings.swift b/PlexConnectApp/Settings.swift
index 06c4fc5..12c4ae1 100644
--- a/PlexConnectApp/Settings.swift
+++ b/PlexConnectApp/Settings.swift
@@ -43,13 +43,41 @@ class cSettings {
], 0
),
"theme": ([
- "Default", "Fanart", "Grids'n'Posters"
+ "Revenant", "Default", "Fanart", "Grids'n'Posters"
], 0
),
"themeExternalOverride": ([
"off", "127.0.0.1:1844"
], 0
),
+ "showChannels": ([
+ "Hide", "Show"
+ ], 0
+ ),
+
+ "movieFanart": ([
+ "Hide", "Show"
+ ], 0
+ ),
+
+ "musicFanart": ([
+ "Hide", "Show"
+ ], 0
+ ),
+
+ "tvshowFanart": ([
+ "Hide", "Show"
+ ], 0
+ ),
+
+ "themeTitle": ([
+ "Text", "Banner"
+ ], 0
+ ),
+ "themeMusic": ([
+ "Off", "On"
+ ], 0
+ ),
]
init() {
diff --git a/PlexConnectApp/TVMLTemplates/Default/Movie_PrePlay.xml b/PlexConnectApp/TVMLTemplates/Default/Movie_PrePlay.xml
index c725d45..de60e68 100644
--- a/PlexConnectApp/TVMLTemplates/Default/Movie_PrePlay.xml
+++ b/PlexConnectApp/TVMLTemplates/Default/Movie_PrePlay.xml
@@ -15,7 +15,7 @@ See LICENSE.txt for this sample’s licensing information
-
+
{{TEXT(Director)}}
@@ -28,7 +28,7 @@ See LICENSE.txt for this sample’s licensing information
{{VAL(MediaContainer/Video/Producer/tag)}}
-
+
{{TEXT(Actors)}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Channels.xml b/PlexConnectApp/TVMLTemplates/Revenant/Channels.xml
new file mode 100755
index 0000000..98983e4
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Channels.xml
@@ -0,0 +1,114 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{{PMSLOOP(all)}}{{
+{{XML(/channels/all)}}{{
+
+{{IF({{VAL(MediaContainer/size)}})}}{{
+
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+
+
+{{IF({{TABLE(${{VAL(key)}}:0:/video/:1)}})}}{{
+
+
+
+ {{TEXT(video)}}
+
+}}
+
+
+{{IF({{TABLE(${{VAL(key)}}:0:/music/:1)}})}}{{
+
+
+
+ {{TEXT(music)}}
+
+}}
+
+
+{{IF({{TABLE(${{VAL(key)}}:0:/photos/:1)}})}}{{
+
+
+
+ {{TEXT(photos)}}
+
+}}
+}}
+
+
+}}
+
+}}
+}}
+
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Homemovie_Directory.xml b/PlexConnectApp/TVMLTemplates/Revenant/Homemovie_Directory.xml
new file mode 100755
index 0000000..9a6857b
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Homemovie_Directory.xml
@@ -0,0 +1,53 @@
+
+
+{{XML()}}
+{{
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+
+ {{XML({{VAL(key)}})}}{{
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+
+
+ }}
+ {{COPY(MediaContainer/Video)}}{{
+
+
+
+
+ }}
+
+
+
+
+ }}
+
+ }}
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Homemovie_Folder.xml b/PlexConnectApp/TVMLTemplates/Revenant/Homemovie_Folder.xml
new file mode 100755
index 0000000..576d5c3
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Homemovie_Folder.xml
@@ -0,0 +1,59 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+
+
+
+
+ }}
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+
+
+
+
+
+ }}
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Library.xml b/PlexConnectApp/TVMLTemplates/Revenant/Library.xml
new file mode 100755
index 0000000..2a21264
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Library.xml
@@ -0,0 +1,454 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+
+
+
+
+
+ {{PMSLOOP(owned)}}{{
+ {{XML(/library/onDeck)}}{{
+
+
+
+ Discover
+ {{USRVAL(name)}}
+
+
+
+
+ Reload
+
+ {{IF({{CHK("{{PMSCNT()}}">"1")}})}}{{
+
+
+
+
+ }}
+
+
+ Switch User
+
+
+
+ Search
+
+
+
+ Settings
+
+
+
+
+
+ {{IFNODE(MediaContainer/Video)}}{{
+
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+ {{IF({{CHK("{{VAL(type:)}}"=="episode")}})}}{{
+
+
+
+
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="movie")}})}}{{
+
+
+
+
+
+
+
+ }}
+ }}
+
+
+ }}
+ }}
+
+ {{XML(/library/recentlyAdded)}}{{
+
+
+ Recently Added Television
+
+
+ {{IFNODE(MediaContainer/Directory)}}{{
+ {{COPY(MediaContainer/Directory)}}{{
+ {{IF({{CHK("{{VAL(type:)}}"=="season")}})}}{{
+ {{SET(noItems:false)}}
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"!="season")}})}}{{
+
+ }}
+ }}
+ }}
+
+
+
+
+
+
+ Recently Added Movies
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+ {{IF({{VAL(viewOffset)}})}}{{
+
+
+
+
+
+
+
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+
+
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+
+
+ }}
+
+
+
+ }}
+ }}
+
+
+
+
+ {{XML({{PATH(/hubs)}})}}{{
+ {{IFNODE(MediaContainer/Hub)}}{{
+ {{COPY(MediaContainer/Hub)}}{{
+ {{IF({{CHK("{{VAL(hubIdentifier:)}}"=="home.music.recent")}})}}{{
+
+
+
+ {{COPY(Directory)}}{{
+
+
+
+
+
+ }}
+
+
+ }}
+ }}
+ }}
+ }}
+ }}
+
+ {{XML(/library/sections)}}{{
+
+
+
+ {{COPY(MediaContainer/Directory)}}
+ {{
+ {{SET(noItems:false)}}
+ {{IF({{CHK("{{VAL(type:)}}"=="movie")}})}}
+ {{
+ {{IF({{CHK("{{VAL(scanner:)}}"=="Plex Video Files Scanner")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+ }}
+ {{IF(!{{CHK("{{VAL(scanner:)}}"=="Plex Video Files Scanner")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+ }}
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="show")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="artist")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="photo")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+ }}
+ }}
+
+
+ }}
+
+
+
+ {{XML(/playlists/)}}{{
+ {{IFNODE(MediaContainer/Playlist)}}{{
+
+
+
+ {{COPY(MediaContainer/Playlist)}}
+ {{
+ {{SET(noItems:false)}}
+ {{IF({{CHK("{{VAL(type:)}}"=="playlist")}})}}
+ {{
+ {{IF({{CHK("{{VAL(playlistType:)}}"=="video")}})}}
+ {{
+
+
+ {{IF({{CHK("{{VAL(leafCount)}}">"0")}})}}{{
+
+
+ {{VAL(leafCount)}}
+
+ }}
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(playlistType:)}}"=="audio")}})}}
+ {{
+
+
+ {{IF({{CHK("{{VAL(leafCount)}}">"0")}})}}{{
+
+
+ {{VAL(leafCount)}}
+
+ }}
+
+
+
+ }}
+ }}
+ }}
+
+
+ }}
+ }}
+
+
+ {{IF({{CHK("{{SETTING(showChannels)}}"=="Show")}})}}{{
+
+ {{XML({{PATH(/channels/all)}})}}{{
+ {{IFNODE(MediaContainer/Directory)}}{{
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+ {{IF({{TABLE(${{VAL(key)}}:0:/video/:1)}})}}{{
+
+
+
+ Video
+
+ }}
+ {{IF({{TABLE(${{VAL(key)}}:0:/music/:1)}})}}{{
+
+
+
+ Music
+
+ }}
+ {{IF({{TABLE(${{VAL(key)}}:0:/photos/:1)}})}}{{
+
+
+
+ Photos
+
+ }}
+ }}
+
+
+ }}
+ }}
+ }}
+
+ }}
+ {{PMS(plex.tv)}}{{
+ {{XML(/pms/playlists/queue/unwatched)}}{{
+ {{IF({{CHK("{{VAL(MediaContainer/size)}}">"0")}})}}{{
+
+
+
+ {{COPY(MediaContainer/Video)}}{{
+
+
+
+
+
+ }}
+
+
+ }}
+ }}
+ }}
+
+
+
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Servers Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/List.xml b/PlexConnectApp/TVMLTemplates/Revenant/List.xml
new file mode 100755
index 0000000..e601b03
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/List.xml
@@ -0,0 +1,61 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+
+
+
+
+
+
+
+}}
+{{COPY(MediaContainer/Video)}}{{
+{{SET(noItems:false)}}
+
+
+
+}}
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Main.xml b/PlexConnectApp/TVMLTemplates/Revenant/Main.xml
new file mode 100755
index 0000000..fe1f820
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Main.xml
@@ -0,0 +1,69 @@
+
+
+{{SET(noXml:true)}}
+{{PMS(plex.tv)}}{{
+{{XML(/api/home/users)}}{{
+
+{{IFNODE(errors)}}{{
+
+{{SET(noXml:false)}}
+
+
+ PlexConnect
+ loading...
+
+
+}}
+
+{{IFNODE(MediaContainer)}}{{
+{{SET(noXml:false)}}
+
+{{IF({{CHK("{{VAL(MediaContainer/size:0)}}"=="1")}})}}{{
+
+
+
+ PlexConnect
+ loading...
+
+
+}}
+
+{{IF(!{{CHK("{{VAL(MediaContainer/size:0)}}"=="1")}})}}{{
+
+
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noXml)}})}}{{
+
+
+
+ PlexConnect
+ {{TEXT(No answer from plex.tv. For now I'm stuck.)}}
+
+
+}}
+
+
+}}
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Main_HomeUsers.xml b/PlexConnectApp/TVMLTemplates/Revenant/Main_HomeUsers.xml
new file mode 100755
index 0000000..dd82145
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Main_HomeUsers.xml
@@ -0,0 +1,65 @@
+
+
+{{PMS(plex.tv)}}{{
+{{XML(/api/home/users)}}{{
+
+
+
+
+
+
+
+
+
+
+
+ Settings
+
+
+
+
+
+ {{COPY(MediaContainer/User)}}{{
+
+
+
+
+
+
+ }}
+
+
+
+
+}}
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Main_SignIn.xml b/PlexConnectApp/TVMLTemplates/Revenant/Main_SignIn.xml
new file mode 100755
index 0000000..bf46c81
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Main_SignIn.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ PlexConnect
+ {{TEXT(To start using all your Plex Services, Sign In with your MyPlex ID.)}}
+
+
+
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_Actor.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Actor.xml
new file mode 100644
index 0000000..e030f55
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Actor.xml
@@ -0,0 +1,65 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+ {{SET(actorPath:{{PATH()}})}}
+ {{SET(sectionID:{{VAL(MediaContainer/librarySectionID)}})}}
+
+
+ {{XML(/library/metadata/{{VAL(MediaContainer/Video/ratingKey)}})}}{{
+ {{COPY(MediaContainer/Video)}}{{
+ {{COPY(Role)}}{{
+ {{IF({{CHK("{{GET(actorPath)}}"=="/library/sections/{{GET(sectionID)}}/actor/{{VAL(id)}}")}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+
+
+
+
+ }}
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_AudioPopUp.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_AudioPopUp.xml
new file mode 100755
index 0000000..bbc8f00
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_AudioPopUp.xml
@@ -0,0 +1,47 @@
+
+{{XML()}}{{
+{{SET(partID:{{VAL(MediaContainer/Video/Media/Part/id)}})}}
+{{SET(SelectedFound:false)}}
+
+
+ Audio tracks:
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"=="2")}})}}{{
+ {{IF({{VAL(selected)}})}}{{
+ {{SET(SelectedFound:true)}}
+
+ }}
+ {{IF(!{{VAL(selected)}})}}{{
+ {{IF(!{{VAL(default)}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"=="2")}})}}{{
+ {{IF(!{{VAL(selected)}})}}{{
+ {{IF({{VAL(default)}})}}{{
+ {{IF({{CHK("{{GET(SelectedFound)}}"=="true")}})}}{{
+
+ }}
+ {{IF({{CHK("{{GET(SelectedFound)}}"=="false")}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+ }}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_Directory.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Directory.xml
new file mode 100755
index 0000000..65af125
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Directory.xml
@@ -0,0 +1,58 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+
+
+
+
+}}
+
+{{COPY(MediaContainer/Video)}}{{
+{{SET(noItems:false)}}
+
+
+
+
+
+}}
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_Filters.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Filters.xml
new file mode 100755
index 0000000..12384ca
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Filters.xml
@@ -0,0 +1,57 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}
+{{
+
+
+
+
+ {{IFNODE(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+
+ {{VAL(MediaContainer/title1)}}
+ {{COPY(MediaContainer/Directory)}}{{
+ {{IF({{VAL(prompt)}})}}{{
+
+ }}
+ {{IF(!{{VAL(prompt)}})}}{{
+ {{IF({{CHK("{{VAL(key:)}}"=="folder")}})}}{{
+
+ }}
+ {{IF(!{{CHK("{{VAL(key:)}}"=="folder")}})}}{{
+ {{IF({{CHK("{{VAL(secondary:)}}"=="1")}})}}{{
+
+ }}
+ {{IF(!{{CHK("{{VAL(secondary:)}}"=="1")}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+
+ }}
+
+ }}
+ }}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_Grid.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Grid.xml
new file mode 100755
index 0000000..1cce930
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Grid.xml
@@ -0,0 +1,122 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+{{IF({{CHK("{{VAL(MediaContainer/size)}}">"0")}})}}{{
+{{SET(noItems:false)}}
+}}
+
+
+
+
+ {{IFNODE(MediaContainer/Playlist)}}{{
+
+
+ Playlists
+
+
+
+
+ {{COPY(MediaContainer/Playlist)}}{{
+
+
+
+
+ {{VAL(year:)}}
+
+ }}
+
+
+
+
+ }}
+ {{SET(sectionID:{{VAL(MediaContainer/librarySectionID)}})}}
+ {{IFNODE(MediaContainer/Video)}}{{
+
+
+
+
+
+
+
+
+ Search
+
+
+
+ Reload
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+
+
+
+
+ }}
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+ {{IF({{VAL(viewOffset)}})}}{{
+
+
+
+
+
+
+
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+
+
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+
+
+ }}
+
+
+
+ }}
+ }}
+
+
+
+
+
+ }}
+
+}}
+}}
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_MorePopUp.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_MorePopUp.xml
new file mode 100755
index 0000000..2129e64
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_MorePopUp.xml
@@ -0,0 +1,19 @@
+
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_MovieContext.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_MovieContext.xml
new file mode 100755
index 0000000..560d90e
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_MovieContext.xml
@@ -0,0 +1,42 @@
+
+
+{{XML()}}{{
+
+
+
+
+{{SET(showMarkWatched:false)}}
+{{SET(showMarkUnwatched:false)}}
+{{IF({{VAL(MediaContainer/Video/viewOffset:0)}})}}{{
+ {{SET(showMarkWatched:true)}}
+ {{SET(showMarkUnwatched:true)}}
+}}
+{{IF({{VAL(MediaContainer/Video/viewCount:0)}})}}{{
+ {{SET(showMarkUnwatched:true)}}
+}}
+{{IF(!{{VAL(MediaContainer/Video/viewCount:0)}})}}{{
+ {{SET(showMarkWatched:true)}}
+}}
+{{IF({{GET(showMarkWatched)}})}}{{
+
+}}
+{{IF({{GET(showMarkUnwatched)}})}}{{
+
+}}
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_OnDeck.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_OnDeck.xml
new file mode 100755
index 0000000..6642b84
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_OnDeck.xml
@@ -0,0 +1,136 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(sectionID:{{VAL(MediaContainer/librarySectionID)}})}}
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Filters
+
+
+
+ Search
+
+
+
+ Reload
+
+
+
+ {{XML(/hubs/sections/{{VAL(MediaContainer/librarySectionID)}}/?count=20&excludeFields=summary)}}{{
+ {{IFNODE(MediaContainer/Hub)}}{{
+ {{SET(noItems:false)}}
+
+ {{COPY(MediaContainer/Hub)}}{{
+ {{IF({{CHK("{{VAL(size)}}">"0")}})}}{{
+ {{IF({{CHK("{{VAL(hubIdentifier)}}"="movie.inprogress")}})}}{{
+
+
+
+ {{COPY(Video)}}{{
+ {{IF({{VAL(viewOffset)}})}}{{
+
+
+
+
+
+
+
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+
+
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+
+
+ }}
+
+
+
+ }}
+ }}
+
+
+ }}
+ }}
+ }}
+ {{COPY(MediaContainer/Hub)}}{{
+ {{IF({{CHK("{{VAL(size)}}">"0")}})}}{{
+ {{IF(!{{CHK("{{VAL(hubIdentifier)}}"="movie.inprogress")}})}}{{
+
+
+
+ {{COPY(Video)}}{{
+ {{IF({{VAL(viewOffset)}})}}{{
+
+
+
+
+
+
+
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+
+
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+
+
+ }}
+
+
+
+ }}
+ }}
+
+
+ }}
+ }}
+ }}
+ }}
+ }}
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_PrePlay.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_PrePlay.xml
new file mode 100755
index 0000000..12b0662
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_PrePlay.xml
@@ -0,0 +1,263 @@
+
+
+{{XML(?includeExtras=1&includeRelated=1&includeRelatedCount=10&includeReviews=1)}}{{
+{{SET(sectionID:{{VAL(MediaContainer/librarySectionID)}})}}
+{{SET(AudioIsDefault:true)}}
+{{SET(SubsIsDefault:true)}}
+
+
+
+
+
+
+ {{IF({{CHK("{{SETTING(movieFanart)}}"=="Show")}})}}{{
+
+ }}
+
+
+
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Video/Director)}}{{
+
+ }}
+
+
+
+
+{{COPY(MediaContainer/Video/Role)}}{{
+
+}}
+
+
+
+
+
+
+
+ {{IF({{VAL(MediaContainer/Video/audienceRating:0)}})}}{{
+ {{EVAL({{VAL(MediaContainer/Video/audienceRating:0)}}*10)}}%
+ }}
+ {{IF({{VAL(MediaContainer/Video/audienceRatingImage:0)}})}}{{
+ }}
+
+
+ {{DURATION({{VAL(MediaContainer/Video/duration)}})}}
+
+ {{IF({{VAL(MediaContainer/Video/contentRating)}})}}{{
+
+ }}
+
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="1080")}})}}{{HD 1080p}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="720")}})}}{{HD 720p}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="2k")}})}}{{2K}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="4k")}})}}{{4K}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="sd")}})}}{{SD}}
+
+
+
+
+
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="aac")}})}}{{AAC}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="ac3")}})}}{{AC3}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="asf")}})}}{{ASF}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="dca")}})}}{{DTS}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="mp2")}})}}{{MPEG}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="mp3")}})}}{{MP3}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="wmav2")}})}}{{WMA}}
+
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioChannels)}}"=="1")}})}}{{1.0}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioChannels)}}"=="2")}})}}{{2.0}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioChannels)}}"=="6")}})}}{{5.1}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioChannels)}}"=="8")}})}}{{7.1}}
+
+
+
+
+
+
+
+
+
+ {{IF(!{{VAL(MediaContainer/Video/viewOffset)}})}}{{
+
+
+ {{TEXT(Play)}}
+
+ }}
+ {{IF({{VAL(MediaContainer/Video/viewOffset)}})}}{{
+
+
+
+ {{TEXT(Resume)}}
+
+ }}
+
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Extras/Video/index:)}}"=="1")}})}}{{
+
+
+ {{TEXT(Trailer)}}
+
+ }}
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"="2")}})}}{{
+ {{IF({{CHK("{{VAL(selected)}}"="1")}})}}{{
+ {{SET(AudioIsDefault:false)}}
+
+
+
+
+ }}
+ }}
+ }}
+ {{IF({{GET(AudioIsDefault)}})}}{{
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"="2")}})}}{{
+ {{IF({{CHK("{{VAL(default)}}"="1")}})}}{{
+
+
+
+
+ }}
+ }}
+ }}
+ }}
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"="3")}})}}{{
+ {{IF({{CHK("{{VAL(selected)}}"="1")}})}}{{
+ {{SET(SubsIsDefault:false)}}
+
+
+
+
+ }}
+ }}
+ }}
+ {{IF({{GET(SubsIsDefault)}})}}{{
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"="3")}})}}{{
+ {{IF({{CHK("{{VAL(default)}}"="1")}})}}{{
+
+
+
+
+ }}
+ }}
+ }}
+ }}
+
+
+ {{TEXT(More)}}
+
+
+
+
+
+
+
+
+
+
+{{XML(/library/metadata/{{VAL(MediaContainer/Video/ratingKey)}}/similar)}}{{
+{{IFNODE(MediaContainer/Video:)}}{{
+
+
+ {{TEXT(Related Movies)}}
+
+
+ {{COPY(MediaContainer/Video)}}
+ {{
+
+
+
+
+ }}
+
+
+}}
+}}
+
+{{IFNODE(MediaContainer/Video/Extras/Video:)}}{{
+
+
+
+ {{COPY(MediaContainer/Video/Extras/Video)}}
+ {{
+
+
+
+ {{TABLE({{VAL(extraType)}}:{{TEXT(Clip)}}:1:{{TEXT(Trailer)}}:2:{{TEXT(Deleted Scene)}}:3:{{TEXT(Interview)}}:4:{{TEXT(Music Video)}}:5:{{TEXT(Behind the Scenes)}}:6:{{TEXT(Scene)}}:7:{{TEXT(Live Video)}}:8:{{TEXT(Lyrics Video)}})}}
+
+ }}
+
+
+}}
+
+
+{{SET(sectionID:{{VAL(MediaContainer/librarySectionID)}})}}
+
+
+
+
+ {{COPY(MediaContainer/Video/Role)}}
+ {{
+
+
+
+
+
+ }}
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_PrePlayDescription.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_PrePlayDescription.xml
new file mode 100755
index 0000000..8310faa
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_PrePlayDescription.xml
@@ -0,0 +1,19 @@
+
+
+{{XML()}}{{
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_Secondary.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Secondary.xml
new file mode 100755
index 0000000..27fa55c
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_Secondary.xml
@@ -0,0 +1,54 @@
+
+
+{{XML()}}
+{{
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+
+ {{XML({{VAL(key)}})}}{{
+
+
+
+
+ {{COPY(MediaContainer/Video)}}{{
+
+
+
+
+ }}
+
+
+
+ }}
+
+ }}
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Movie_SubsPopUp.xml b/PlexConnectApp/TVMLTemplates/Revenant/Movie_SubsPopUp.xml
new file mode 100755
index 0000000..d53afbf
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Movie_SubsPopUp.xml
@@ -0,0 +1,47 @@
+
+{{XML()}}{{
+{{SET(partID:{{VAL(MediaContainer/Video/Media/Part/id)}})}}
+{{SET(SelectedFound:false)}}
+
+
+ Available subtitles:
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"=="3")}})}}{{
+ {{IF({{VAL(selected)}})}}{{
+ {{SET(SelectedFound:true)}}
+
+ }}
+ {{IF(!{{VAL(selected)}})}}{{
+ {{IF(!{{VAL(default)}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"=="3")}})}}{{
+ {{IF(!{{VAL(selected)}})}}{{
+ {{IF({{VAL(default)}})}}{{
+ {{IF({{CHK("{{GET(SelectedFound)}}"=="true")}})}}{{
+
+ }}
+ {{IF({{CHK("{{GET(SelectedFound)}}"=="false")}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+ }}
+
+
+}}
\ No newline at end of file
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Album.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Album.xml
new file mode 100755
index 0000000..c131741
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Album.xml
@@ -0,0 +1,105 @@
+
+{{CUT({{GET(noItems)}})}}
+{{
+{{SET(noItems:true)}}
+{{SET(videoItems:false)}}
+
+{{XML()}}
+{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Play all
+
+
+
+ Shuffle all
+
+
+
+ Go to Artist
+
+
+
+
+
+
+
+
+
+ {{VAL(MediaContainer/parentYear)}}
+
+
+ {{IF({{VAL(MediaContainer/summary)}})}}
+ {{
+
+ }}
+
+
+
+
+{{COPY(MediaContainer/Track)}}{{
+ {{SET(noItems:false)}}
+ {{IF(!{{VAL(primaryExtraKey)}})}}{{
+
+ {{VAL(index)}}
+
+
+ {{DURATION_HMS({{VAL(duration)}})}}
+
+ }}
+ {{IF({{VAL(primaryExtraKey)}})}}{{
+
+ {{VAL(index)}}
+
+
+ {{DURATION_HMS({{VAL(duration)}})}}
+
+ {{SET(videoItems:true)}}
+
+ }}
+ }}
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}
+{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_AlbumDescription.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_AlbumDescription.xml
new file mode 100755
index 0000000..52617b9
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_AlbumDescription.xml
@@ -0,0 +1,19 @@
+
+
+{{XML()}}{{
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Albums.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Albums.xml
new file mode 100755
index 0000000..ccd4aef
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Albums.xml
@@ -0,0 +1,91 @@
+
+{{CUT({{GET(noItems)}})}}
+{{
+{{SET(noItems:true)}}
+{{XML()}}
+{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Play all
+
+
+
+ Shuffle all
+
+
+
+ Now playing
+
+
+
+
+
+
+
+
+ {{VAL(MediaContainer/parentYear)}}
+
+
+ {{IF({{VAL(MediaContainer/summary)}})}}
+ {{
+
+ }}
+
+
+
+{{COPY(MediaContainer/Track)}}
+{{
+{{SET(noItems:false)}}
+
+
+
+
+
+
+
+ {{DURATION_HMS({{VAL(duration)}})}}
+
+
+
+
+}}
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}
+{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Artist.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Artist.xml
new file mode 100755
index 0000000..871818e
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Artist.xml
@@ -0,0 +1,130 @@
+
+
+{{XML()}}{{
+
+
+
+
+
+
+ {{IF({{CHK("{{SETTING(musicFanart)}}"=="Show")}})}}{{
+
+ }}
+
+
+
+
+
+ {{COPY(MediaContainer/Directory/Country)}}{{
+
+ }}
+
+
+
+
+ {{COPY(MediaContainer/Directory/Genre)}}{{
+
+ }}
+
+
+
+
+{{SET(popular:/library/sections/{{VAL(MediaContainer/librarySectionID)}}/search?type=10&artist.id={{VAL(MediaContainer/Directory/ratingKey)}}&group=title&limit=100&ratingCount%3E=1&sort=ratingCount:desc)}}
+{{SET(artist:/library/sections/{{VAL(MediaContainer/librarySectionID)}}/search?type=10&artist.id={{VAL(MediaContainer/Directory/ratingKey)}}&group=title&sort=title:desc)}}
+
+
+
+
+
+
+
+
+ Shuffle all
+
+
+
+ Popular
+
+
+
+ Videos
+
+
+
+
+
+
+{{XML({{PATH()}}/children/)}}{{
+{{IFNODE(MediaContainer/Directory:)}}{{
+
+
+ {{VAL(MediaContainer/size)}}{{TEXT( Album(s))}}
+
+
+ {{COPY(MediaContainer/Directory)}}
+ {{
+
+
+
+
+
+ }}
+
+
+}}
+}}
+{{XML({{PATH()}}/extras/)}}{{
+ {{IFNODE(MediaContainer/Video)}}{{
+
+
+ {{VAL(MediaContainer/size)}}{{TEXT( Music video(s))}}
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+
+
+
+
+ }}
+
+
+ }}
+}}
+
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Description.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Description.xml
new file mode 100755
index 0000000..93043cf
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Description.xml
@@ -0,0 +1,19 @@
+
+
+{{XML()}}{{
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Directory.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Directory.xml
new file mode 100755
index 0000000..502dcba
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Directory.xml
@@ -0,0 +1,47 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+
+
+
+
+}}
+
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Filters.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Filters.xml
new file mode 100755
index 0000000..a5d6c03
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Filters.xml
@@ -0,0 +1,72 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}
+{{
+
+
+
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+ {{IF({{CHK("{{VAL(key:)}}"=="all")}})}}{{
+
+ }}
+ {{IF({{CHK("{{VAL(key:)}}"!="all")}})}}{{
+
+
+ {{IF({{VAL(prompt)}})}}{{
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{VAL(prompt)}})}}{{
+ {{IF({{CHK("{{VAL(key:)}}"=="folder")}})}}{{
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{CHK("{{VAL(key:)}}"=="folder")}})}}{{
+ {{IF({{CHK("{{VAL(secondary:)}}"=="1")}})}}{{
+
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{CHK("{{VAL(secondary:)}}"=="1")}})}}{{
+ {{SET(noItems:false)}}
+
+ }}
+ }}
+ }}
+ }}
+}}
+
+}}
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Grid.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Grid.xml
new file mode 100755
index 0000000..435131a
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Grid.xml
@@ -0,0 +1,94 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Search
+
+
+
+ Reload
+
+
+
+
+
+
+ {{IFNODE(MediaContainer/Directory)}}{{
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+ {{IF({{CHK("{{VAL(type)}}"!="artist")}})}}{{
+
+
+
+
+ {{VAL(year:)}}
+
+ }}
+ {{IF({{CHK("{{VAL(type)}}"=="artist")}})}}{{
+
+
+
+
+
+ }}
+ }}
+
+ }}
+ {{IFNODE(MediaContainer/Playlist)}}{{
+
+ {{COPY(MediaContainer/Playlist)}}{{
+ {{SET(noItems:false)}}
+
+
+
+
+
+ }}
+
+ }}
+
+}}
+
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_List.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_List.xml
new file mode 100644
index 0000000..dea7314
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_List.xml
@@ -0,0 +1,73 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+
+
+
+
+
+ {{IF({{VAL(art)}})}}{{
+
+ }}
+ {{IF(!{{VAL(art)}})}}{{
+
+ }}
+
+
+
+
+
+
+ {{IF({{VAL(Country/tag)}})}}{{
+ Country:
+ }}
+ {{IF({{VAL(Genre/tag)}})}}{{
+ Genre:
+ }}
+
+
+
+
+}}
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_OnDeck.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_OnDeck.xml
new file mode 100644
index 0000000..f07cafd
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_OnDeck.xml
@@ -0,0 +1,169 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Now playing
+
+
+
+ Filters
+
+ {{XML(/playlists?playlistType=audio)}}{{
+ {{IF({{CHK("{{VAL(MediaContainer/size)}}">"0")}})}}{{
+
+
+ Playlists
+
+ }}
+ }}
+
+
+ Search
+
+
+
+ Reload
+
+
+
+
+ {{XML(all?sort=viewCount%3Adesc&excludeFields=summary&limit=15)}}{{
+ {{IFNODE(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+ {{IF({{VAL(thumb)}})}}{{
+
+ }}
+ {{IF(!{{VAL(thumb)}})}}{{
+
+ }}
+
+
+
+ }}
+
+
+ }}
+ }}
+ {{XML(all?type=9&sort=viewCount&excludeFields=summary&X-Plex-Container-Start=0&X-Plex-Container-Size=15)}}{{
+ {{IFNODE(MediaContainer/Directory)}}{{
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+
+
+
+ }}
+
+
+ }}
+ }}
+ {{XML(/hubs/sections/{{VAL(MediaContainer/librarySectionID)}}/?count=15&excludeFields=summary)}}{{
+ {{IFNODE(MediaContainer/Hub)}}{{
+ {{COPY(MediaContainer/Hub)}}{{
+ {{IF({{CHK("{{VAL(size)}}">"0")}})}}{{
+ {{IF(!{{CHK("{{VAL(hubIdentifier)}}"="music.recent.artist")}})}}{{
+ {{IF(!{{CHK("{{VAL(hubIdentifier)}}"="music.recent.genre")}})}}{{
+
+
+
+ {{IFNODE(Directory)}}{{
+ {{COPY(Directory)}}{{
+ {{IF({{CHK("{{VAL(type)}}"="artist")}})}}{{
+
+
+ }}
+ {{IF(!{{CHK("{{VAL(type)}}"="artist")}})}}{{
+
+
+ }}
+
+ {{IF({{VAL(year)}})}}{{
+
+ }}
+ {{IF(!{{VAL(year)}})}}{{
+
+ }}
+
+ }}
+ }}
+ {{IFNODE(Video)}}{{
+ {{COPY(Video)}}{{
+
+
+
+
+
+ }}
+ }}
+
+
+ }}
+ }}
+ }}
+ }}
+ }}
+ }}
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Secondary.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Secondary.xml
new file mode 100755
index 0000000..3f9e836
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Secondary.xml
@@ -0,0 +1,73 @@
+
+
+{{XML()}}
+{{
+
+
+
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+ {{XML({{VAL(key)}})}}{{
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{IF({{CHK("{{VAL(type)}}"!="artist")}})}}{{
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type)}}"=="artist")}})}}{{
+
+
+
+
+ }}
+ }}
+
+
+
+ }}
+
+ }}
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_TrackList.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_TrackList.xml
new file mode 100755
index 0000000..479d08c
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_TrackList.xml
@@ -0,0 +1,89 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Play
+
+
+
+ Shuffle
+
+
+
+ Now Playing
+
+
+
+ Artist
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Track)}}{{
+ {{SET(noItems:false)}}
+
+ {{VAL(index)}}
+
+ {{DURATION_HMS({{VAL(duration)}})}}
+
+ }}
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_VideoPopUp.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_VideoPopUp.xml
new file mode 100755
index 0000000..02e16e0
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_VideoPopUp.xml
@@ -0,0 +1,14 @@
+
+{{XML()}}{{
+
+
+ Select item you want to play:
+
+
+
+
+}}
\ No newline at end of file
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Music_Videos.xml b/PlexConnectApp/TVMLTemplates/Revenant/Music_Videos.xml
new file mode 100755
index 0000000..52a683e
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Music_Videos.xml
@@ -0,0 +1,64 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:false)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Play all
+
+
+
+ Shuffle all
+
+
+
+
+
+
+
+}}
+
+{{XML({{PATH()}}/extras)}}{{
+{{COPY(MediaContainer/Video)}}{{
+{{SET(noItems:false)}}
+
+
+ {{EVAL({{VAL(index)}}-1)}}
+
+
+
+
+
+
+}}
+
+
+
+
+}}
+}}
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_Discover.xml b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_Discover.xml
new file mode 100755
index 0000000..ed48103
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_Discover.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ {{TEXT(Connecting to your Plex Media Servers...)}}
+
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_HomeUsers.xml b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_HomeUsers.xml
new file mode 100755
index 0000000..2c61311
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_HomeUsers.xml
@@ -0,0 +1,58 @@
+
+
+{{PMS(plex.tv)}}{{
+{{XML(/api/home/users)}}{{
+
+
+
+
+
+
+ Home Users
+
+
+
+
+ Settings
+
+
+
+
+
+ {{COPY(MediaContainer/User)}}{{
+
+
+
+
+
+ }}
+
+
+
+
+}}
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_Servers.xml b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_Servers.xml
new file mode 100755
index 0000000..2ebda77
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_Servers.xml
@@ -0,0 +1,104 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+
+
+
+
+
+
+
+ {{TEXT(Plex Media Servers)}}
+
+
+
+
+
+ {{TEXT(Available Plex Media Servers)}}: {{PMSCNT(all)}}
+
+
+{{PMSLOOP(owned)}}{{
+{{SET(noItems:false)}}
+
+
+
+{{IF({{PMSVAL(local)}})}}{{
+
+
+}}
+{{IF(!{{PMSVAL(local)}})}}{{
+
+}}
+
+
+
+
+
+
+ Admin:
+
+ Platform:
+
+
+
+}}
+
+{{PMSLOOP(shared)}}{{
+{{SET(noItems:false)}}
+
+
+
+{{IF({{PMSVAL(local)}})}}{{
+
+
+}}
+{{IF(!{{PMSVAL(local)}})}}{{
+
+}}
+
+
+
+
+
+
+ Admin:
+
+ Platform:
+
+
+
+}}
+
+
+
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInFailed.xml b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInFailed.xml
new file mode 100755
index 0000000..d36627c
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInFailed.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ MyPlex
+ Sign in failed.
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInHomeUserPin.xml b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInHomeUserPin.xml
new file mode 100755
index 0000000..c64d45f
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInHomeUserPin.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+ {{TEXT(MyPlex HomeUser)}}
+ {{TEXT(To finish switching, enter your HomeUser pin.)}}
+
+ 0000
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInPassword.xml b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInPassword.xml
new file mode 100755
index 0000000..af838f7
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInPassword.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ {{TEXT(MyPlex Sign In)}}
+ {{TEXT(To finish MyPlex sign in, enter your password.)}}
+
+ {{TEXT(Password)}}
+
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInUsername.xml b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInUsername.xml
new file mode 100755
index 0000000..39119fd
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/MyPlex_SignInUsername.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ {{TEXT(MyPlex Sign In)}}
+ {{TEXT(To sign in to MyPlex, enter your Email address, username or Plex forum username.)}}
+
+ {{TEXT(Plex User ID)}}
+
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Photo_Browser.xml b/PlexConnectApp/TVMLTemplates/Revenant/Photo_Browser.xml
new file mode 100755
index 0000000..8633ca5
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Photo_Browser.xml
@@ -0,0 +1,90 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+{{CUT({{GET(noDirs)}})}}{{
+{{SET(noDirs:true)}}
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+{{SET(noDirs:false)}}
+
+
+
+
+}}
+
+
+}}
+
+
+{{CUT({{GET(noPhotos)}})}}{{
+{{SET(noPhotos:true)}}
+
+
+
+
+
+{{COPY(MediaContainer/Photo)}}{{
+{{SET(noItems:false)}}
+{{SET(noPhotos:false)}}
+
+
+
+
+}}
+
+
+}}
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Photo_Filters.xml b/PlexConnectApp/TVMLTemplates/Revenant/Photo_Filters.xml
new file mode 100644
index 0000000..a2dc930
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Photo_Filters.xml
@@ -0,0 +1,70 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}
+{{
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}
+ {{
+ {{IF({{VAL(prompt)}})}}
+ {{
+
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{VAL(prompt)}})}}
+ {{
+ {{IF({{CHK("{{VAL(key:)}}"=="folder")}})}}
+ {{
+
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{CHK("{{VAL(key:)}}"=="folder")}})}}
+ {{
+ {{IF({{CHK("{{VAL(secondary:)}}"=="1")}})}}
+ {{
+
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{CHK("{{VAL(secondary:)}}"=="1")}})}}
+ {{
+
+ {{SET(noItems:false)}}
+
+ }}
+ }}
+ }}
+ }}
+}}
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ TITLE
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Photo_OnDeck.xml b/PlexConnectApp/TVMLTemplates/Revenant/Photo_OnDeck.xml
new file mode 100644
index 0000000..eac7317
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Photo_OnDeck.xml
@@ -0,0 +1,138 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+{{SET(sectionId:{{VAL(MediaContainer/librarySectionID)}})}}
+
+
+
+
+
+{{XML(all?sort=random&limit=1)}}{{
+{{IFNODE(MediaContainer/Photo)}}{{
+{{SET(noItems:false)}}
+
+
+
+
+
+
+
+ Filters
+
+ {{XML(/playlists?playlistType=photo)}}{{
+ {{IF({{CHK("{{VAL(MediaContainer/size)}}">"0")}})}}{{
+
+
+ Playlists
+
+ }}
+ }}
+
+
+ Search
+
+
+
+
+ Reload
+
+
+
+}}
+}}
+
+
+{{XML(all?sort=title%3Adesc)}}{{
+{{IFNODE(MediaContainer/Directory)}}{{
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+
+
+ }}
+
+
+}}
+}}
+
+{{XML(recentlyAdded?X-Plex-Container-Start=0&X-Plex-Container-Size=25)}}{{
+{{IFNODE(MediaContainer/Photo)}}{{
+
+
+ Recently Added Photos
+
+
+ {{COPY(MediaContainer/Photo)}}{{
+
+
+
+
+
+ }}
+
+
+}}
+}}
+{{XML(/hubs/sections/{{GET(sectionId)}})}}{{
+{{IFNODE(MediaContainer/Hub)}}{{
+{{COPY(MediaContainer/Hub)}}{{
+{{IF({{CHK("{{VAL(hubIdentifier)}}"!="photo.recent")}})}}{{
+
+
+
+ {{COPY(Photo)}}{{
+
+
+
+
+
+ }}
+
+
+}}
+}}
+}}
+}}
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ TITLE
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Photo_Parade.xml b/PlexConnectApp/TVMLTemplates/Revenant/Photo_Parade.xml
new file mode 100755
index 0000000..8119314
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Photo_Parade.xml
@@ -0,0 +1,18 @@
+
+
+{{XML(recentlyAdded?X-Plex-Container-Start=0&X-Plex-Container-Size=20)}}{{
+
+
+
+{{COPY(MediaContainer/Photo)}}{{
+{{IF({{VAL(thumb:)}})}}{{
+
+}}
+}}
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Photo_Secondary.xml b/PlexConnectApp/TVMLTemplates/Revenant/Photo_Secondary.xml
new file mode 100644
index 0000000..159c003
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Photo_Secondary.xml
@@ -0,0 +1,63 @@
+
+
+{{XML()}}
+{{
+
+
+
+
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+
+ {{XML({{VAL(key)}})}}{{
+
+
+
+
+ {{COPY(MediaContainer/Photo)}}{{
+
+
+
+
+ }}
+
+
+
+ }}
+
+ }}
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Photos.xml b/PlexConnectApp/TVMLTemplates/Revenant/Photos.xml
new file mode 100755
index 0000000..befd11a
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Photos.xml
@@ -0,0 +1,14 @@
+
+
+{{XML()}}{{
+
+
+{{COPY(MediaContainer/Photo)}}{{
+ {{PHOTOURL()}}
+}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/PlayAudio.xml b/PlexConnectApp/TVMLTemplates/Revenant/PlayAudio.xml
new file mode 100755
index 0000000..40105f3
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/PlayAudio.xml
@@ -0,0 +1,39 @@
+
+
+{{XML()}}{{
+
+
+ {{PMSVAL(uri)}}
+ {{PMSVAL(accessToken)}}
+
+{{COPY(MediaContainer/Track)}}
+{{
+
+}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/PlayVideo.xml b/PlexConnectApp/TVMLTemplates/Revenant/PlayVideo.xml
new file mode 100755
index 0000000..24af5b3
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/PlayVideo.xml
@@ -0,0 +1,63 @@
+
+
+{{XML()}}{{
+
+
+ {{PMSVAL(uri)}}
+ {{PMSVAL(accessToken)}}
+
+{{COPY(MediaContainer/Video)}}
+{{
+
+}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Playlists_Audio.xml b/PlexConnectApp/TVMLTemplates/Revenant/Playlists_Audio.xml
new file mode 100755
index 0000000..1ea9022
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Playlists_Audio.xml
@@ -0,0 +1,78 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+ {{TEXT(Shuffle)}}
+
+
+
+
+
+
+
+
+
+ {{TEXT(Now Playing)}}
+
+
+
+
+
+
+{{COPY(MediaContainer/Track)}}{{
+
+{{IF({{CHK("{{VAL(type)}}"=="track")}})}}{{
+{{SET(noItems:false)}}
+
+
+ {{DURATION_HMS({{VAL(duration)}})}}
+
+
+
+
+
+
+}}
+}}
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Playlists_List.xml b/PlexConnectApp/TVMLTemplates/Revenant/Playlists_List.xml
new file mode 100755
index 0000000..1afff3a
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Playlists_List.xml
@@ -0,0 +1,123 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+
+
+
+ {{TEXT(Playlists)}}
+
+
+
+
+{{PMS(plex.tv)}}{{
+{{XML(/api/playlists/queue)}}{{
+{{CUT({{GET(noQueueLists)}})}}{{
+{{SET(noQueueLists)}}
+
+
+ {{TEXT(MyPlex Queue)}}
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+{{SET(noQueueLists:false)}}
+
+
+
+
+
+
+
+
+}}
+
+}}
+}}
+}}
+
+
+{{PMSLOOP(all)}}{{
+{{XML()}}{{
+{{CUT({{GET(noVideoLists)}})}}{{
+{{SET(noVideoLists:true)}}
+
+
+ {{TEXT(Video)}} - {{PMSVAL(name)}}
+
+
+{{COPY(MediaContainer/Playlist)}}{{
+{{IF({{CHK("{{VAL(playlistType)}}"=="video")}})}}{{
+{{SET(noItems:false)}}
+{{SET(noVideoLists:false)}}
+
+
+ {{VAL(leafCount)}}
+
+
+
+
+
+
+}}
+}}
+
+}}
+}}
+}}
+
+
+{{PMSLOOP(all)}}{{
+{{XML()}}{{
+{{CUT({{GET(noAudioLists)}})}}{{
+{{SET(noAudioLists:true)}}
+
+
+ {{TEXT(Audio)}} - {{PMSVAL(name)}}
+
+
+{{COPY(MediaContainer/Playlist)}}{{
+{{IF({{CHK("{{VAL(playlistType)}}"=="audio")}})}}{{
+{{SET(noItems:false)}}
+{{SET(noAudioLists:false)}}
+
+
+ {{VAL(leafCount)}}
+
+
+
+
+
+
+}}
+}}
+
+}}
+}}
+}}
+
+
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Playlists_Video.xml b/PlexConnectApp/TVMLTemplates/Revenant/Playlists_Video.xml
new file mode 100755
index 0000000..3ef0f17
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Playlists_Video.xml
@@ -0,0 +1,110 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+ {{TEXT(Shuffle)}}
+
+
+
+
+
+
+
+
+
+
+
+{{COPY(MediaContainer/Video)}}{{
+
+{{IF({{CHK("{{VAL(type)}}"=="movie")}})}}{{
+{{SET(noItems:false)}}
+
+
+
+
+
+
+
+
+
+
+}}
+
+
+{{IF({{CHK("{{VAL(type)}}"=="episode")}})}}{{
+{{SET(noItems:false)}}
+
+
+
+
+
+
+
+
+
+
+
+}}
+
+
+{{IF({{CHK("{{VAL(type)}}"=="clip")}})}}{{
+{{SET(noItems:false)}}
+
+
+
+
+
+
+
+
+
+
+}}
+}}
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Search.xml b/PlexConnectApp/TVMLTemplates/Revenant/Search.xml
new file mode 100644
index 0000000..296be42
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Search.xml
@@ -0,0 +1,217 @@
+
+
+
+
+
+
+
+
+
+
+
+{{XML()}}{{
+
+{{CUT({{GET(noMovies)}})}}{{
+{{SET(noMovies:true)}}
+
+
+
+{{COPY(MediaContainer/Video)}}{{
+{{IF({{CHK("{{VAL(type:)}}"=="movie")}})}}{{
+{{SET(noMovies:false)}}
+{{IF({{VAL(viewOffset)}})}}{{
+
+
+
+
+
+
+
+
+}}
+{{IF(!{{VAL(viewOffset)}})}}{{
+
+
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+
+
+ }}
+
+
+
+}}
+}}
+}}
+
+
+}}
+
+
+{{CUT({{GET(noShows)}})}}{{
+{{SET(noShows:true)}}
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{IF({{CHK("{{VAL(type:)}}"=="show")}})}}{{
+{{SET(noShows:false)}}
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+}}
+}}
+
+
+}}
+
+
+{{CUT({{GET(noEpisodes)}})}}{{
+{{SET(noEpisodes:true)}}
+
+
+
+{{COPY(MediaContainer/Video)}}{{
+{{IF({{CHK("{{VAL(type:)}}"=="episode")}})}}{{
+{{SET(noEpisodes:false)}}
+
+
+
+ {{IF({{VAL(viewOffset)}})}}{{
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+ }}
+ }}
+
+
+
+
+}}
+}}
+
+
+}}
+
+
+{{CUT({{GET(noAlbums)}})}}{{
+{{SET(noAlbums:true)}}
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{IF({{CHK("{{VAL(type:)}}"=="album")}})}}{{
+{{SET(noAlbums:false)}}
+
+
+
+
+
+}}
+}}
+
+
+}}
+
+
+{{CUT({{GET(noArtists)}})}}{{
+{{SET(noArtists:true)}}
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{IF({{CHK("{{VAL(type:)}}"=="artist")}})}}{{
+{{SET(noArtists:false)}}
+
+
+
+
+}}
+}}
+
+
+}}
+
+
+{{CUT({{GET(noTracks)}})}}{{
+{{SET(noTracks:true)}}
+
+
+
+{{COPY(MediaContainer/Track)}}{{
+{{IF({{CHK("{{VAL(type:)}}"=="track")}})}}{{
+{{SET(noTracks:false)}}
+
+
+
+
+}}
+}}
+
+
+}}
+
+}}
+
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Search_All.xml b/PlexConnectApp/TVMLTemplates/Revenant/Search_All.xml
new file mode 100644
index 0000000..a235263
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Search_All.xml
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{CUT({{GET(noMovies)}})}}{{
+ {{SET(noMovies:true)}}
+
+
+ {{PMSLOOP(all)}}{{
+ {{XML()}}{{
+ {{SET(noItems:true)}}
+ {{CUT({{GET(noItems)}})}}{{
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{IF({{CHK("{{VAL(type:)}}"=="movie")}})}}{{
+ {{SET(noMovies:false)}}
+ {{SET(noItems:false)}}
+ {{IF({{VAL(viewOffset)}})}}{{
+
+
+
+
+
+
+
+
+
+ }}
+
+ {{IF(!{{VAL(viewOffset)}})}}{{
+
+
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+
+
+ }}
+
+
+
+
+ }}
+ }}
+ }}
+
+ }}
+ }}
+ }}
+
+ }}
+
+
+ {{CUT({{GET(noShows)}})}}{{
+ {{SET(noShows:true)}}
+
+
+ {{PMSLOOP(all)}}{{
+ {{XML()}}{{
+ {{SET(noItems:true)}}
+ {{CUT({{GET(noItems)}})}}{{
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{IF({{CHK("{{VAL(type:)}}"=="show")}})}}{{
+ {{SET(noShows:false)}}
+ {{SET(noItems:false)}}
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+
+ }}
+ }}
+
+ }}
+ }}
+ }}
+
+ }}
+
+
+ {{CUT({{GET(noEpisodes)}})}}{{
+ {{SET(noEpisodes:true)}}
+
+
+ {{PMSLOOP(all)}}{{
+ {{XML()}}{{
+ {{SET(noItems:true)}}
+ {{CUT({{GET(noItems)}})}}{{
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{IF({{CHK("{{VAL(type:)}}"=="episode")}})}}{{
+ {{SET(noEpisodes:false)}}
+ {{SET(noItems:false)}}
+
+
+
+ {{IF({{VAL(viewOffset)}})}}{{
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+ }}
+ }}
+
+
+ {{TEXT(S)}}{{VAL(parentIndex)}} • {{TEXT(E)}}{{VAL(index)}}
+
+
+ }}
+ }}
+
+ }}
+ }}
+ }}
+
+ }}
+
+
+ {{CUT({{GET(noAlbums)}})}}{{
+ {{SET(noAlbums:true)}}
+
+
+ {{PMSLOOP(all)}}{{
+ {{XML()}}{{
+ {{SET(noItems:true)}}
+ {{CUT({{GET(noItems)}})}}{{
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{IF({{CHK("{{VAL(type:)}}"=="album")}})}}{{
+ {{SET(noAlbums:false)}}
+ {{SET(noItems:false)}}
+
+
+
+
+
+
+ }}
+ }}
+
+ }}
+ }}
+ }}
+
+ }}
+
+
+ {{CUT({{GET(noArtists)}})}}{{
+ {{SET(noArtists:true)}}
+
+
+ {{PMSLOOP(all)}}{{
+ {{XML()}}{{
+ {{SET(noItems:true)}}
+ {{CUT({{GET(noItems)}})}}{{
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{IF({{CHK("{{VAL(type:)}}"=="artist")}})}}{{
+ {{SET(noArtists:false)}}
+ {{SET(noItems:false)}}
+
+
+
+
+
+ }}
+ }}
+
+ }}
+ }}
+ }}
+
+ }}
+
+
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Settings.xml b/PlexConnectApp/TVMLTemplates/Revenant/Settings.xml
new file mode 100755
index 0000000..2c910c2
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Settings.xml
@@ -0,0 +1,284 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{TEXT(Plex Media Environment)}}
+
+
+
+ {{TEXT(Discover)}}
+ {{TEXT(online:)}} {{PMSCNT(all)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+{{IF(!{{USRVAL(adminname)}})}} {{
+
+ {{TEXT(Sign In)}}
+
+
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+}}
+{{IF({{USRVAL(adminname)}})}} {{
+
+ {{TEXT(Sign Out)}}
+ {{USRVAL(adminname)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+}}
+
+
+
+ {{TEXT(Switch Home User)}}
+ {{USRVAL(name)}}
+
+
+
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+
+
+
+
+
+ {{TEXT(Theme)}}
+ {{SETTING(theme)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(External Override)}}
+ {{SETTING(themeExternalOverride)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(Channels)}}
+ {{SETTING(showChannels)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(Movie FanArt)}}
+ {{SETTING(movieFanart)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(Music FanArt)}}
+ {{SETTING(musicFanart)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(TV Show FanArt)}}
+ {{SETTING(tvshowFanart)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(TV Show Banner)}}
+ {{SETTING(themeTitle)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(Theme Music)}}
+ {{SETTING(themeMusic)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+
+
+
+ {{TEXT(Media Replay)}}
+
+
+
+ {{TEXT(Transcoder Action)}}
+ {{SETTING(transcoderAction)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(Transcode Quality)}}
+ {{SETTING(transcoderQuality)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+ {{TEXT(Remote Bitrate)}}
+ {{SETTING(remoteBitrate)}}
+
+
+
+ PlexConnect
+
+ Revenant v0.2beta
+
+
+
+
+
+
+
+
+
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/SharedLibraries.xml b/PlexConnectApp/TVMLTemplates/Revenant/SharedLibraries.xml
new file mode 100755
index 0000000..e66dcbf
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/SharedLibraries.xml
@@ -0,0 +1,414 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+
+
+
+
+
+ {{PMSLOOP(shared)}}{{
+
+ {{XML(/library/onDeck)}}{{
+
+
+
+ Discover {{PMSVAL(name)}}
+ {{USRVAL(name)}}
+
+
+
+ Reload
+
+ {{IF({{CHK("{{PMSCNT()}}">"1")}})}}{{
+
+
+ {{PMSVAL(name)}}
+
+ }}
+
+
+ Switch User
+
+
+
+ Search
+
+
+
+ Settings
+
+
+
+
+
+
+ {{IFNODE(MediaContainer/Video)}}{{
+
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+ {{IF({{CHK("{{VAL(type:)}}"=="episode")}})}}{{
+
+
+
+
+
+
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="movie")}})}}{{
+
+
+
+
+
+
+
+ }}
+ }}
+
+
+ }}
+ }}
+
+
+ {{XML(/library/recentlyAdded)}}{{
+
+
+ {{IFNODE(MediaContainer/Directory)}}{{
+ {{COPY(MediaContainer/Directory)}}{{
+ {{IF({{CHK("{{VAL(type:)}}"=="season")}})}}{{
+ {{SET(noItems:false)}}
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+
+
+ Recently Added Television
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"!="season")}})}}{{
+
+ }}
+ }}
+ }}
+
+
+
+
+ Recently Added Movies
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+
+
+
+
+ {{IF(!{{VAL(viewCount:0)}})}}{{
+
+
+
+
+ }}
+ {{IF({{VAL(viewOffset:0)}})}}{{
+
+ }}
+
+
+
+
+
+ }}
+
+
+
+ }}
+
+ {{XML(/library/sections)}}{{
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+ {{IF({{CHK("{{VAL(type:)}}"=="movie")}})}}{{
+ {{IF({{CHK("{{VAL(scanner:)}}"=="Plex Video Files Scanner")}})}}{{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+
+
+ }}
+ {{IF(!{{CHK("{{VAL(scanner:)}}"=="Plex Video Files Scanner")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+
+
+ }}
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="show")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="artist")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="photo")}})}}
+ {{
+
+ {{XML({{PATH(/library/sections/{{VAL(key)}}/recentlyAdded)}})}}{{
+
+ }}
+
+
+
+
+
+
+ }}
+ }}
+
+
+ }}
+
+
+
+
+ {{XML(/playlists/)}}{{
+ {{IFNODE(MediaContainer/Playlist)}}{{
+
+
+
+ {{COPY(MediaContainer/Playlist)}}
+ {{
+ {{SET(noItems:false)}}
+ {{IF({{CHK("{{VAL(type:)}}"=="playlist")}})}}
+ {{
+ {{IF({{CHK("{{VAL(playlistType:)}}"=="video")}})}}
+ {{
+
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(playlistType:)}}"=="audio")}})}}
+ {{
+
+
+
+
+ }}
+ }}
+ }}
+
+
+ }}
+ }}
+
+
+ {{IF({{CHK("{{SETTING(showChannels)}}"=="Show")}})}}{{
+
+ {{XML({{PATH(/channels/all)}})}}{{
+ {{IFNODE(MediaContainer/Directory)}}{{
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+ {{IF({{TABLE(${{VAL(key)}}:0:/video/:1)}})}}{{
+
+
+
+ Video
+
+ }}
+ {{IF({{TABLE(${{VAL(key)}}:0:/music/:1)}})}}{{
+
+
+
+ Music
+
+ }}
+ {{IF({{TABLE(${{VAL(key)}}:0:/photos/:1)}})}}{{
+
+
+
+ Photos
+
+ }}
+ }}
+
+
+ }}
+ }}
+ }}
+
+
+ }}
+
+
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Actor.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Actor.xml
new file mode 100644
index 0000000..ae44169
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Actor.xml
@@ -0,0 +1,68 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+ {{SET(actorPath:{{PATH()}})}}
+ {{SET(sectionID:{{VAL(MediaContainer/librarySectionID)}})}}
+
+
+
+
+ {{XML(/library/metadata/{{VAL(MediaContainer/Directory/ratingKey)}})}}{{
+ {{COPY(MediaContainer/Directory)}}{{
+ {{COPY(Role)}}{{
+ {{IF({{CHK("{{GET(actorPath)}}"=="/library/sections/{{GET(sectionID)}}/actor/{{VAL(id)}}")}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+
+
+
+
+ }}
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_AudioPopUp.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_AudioPopUp.xml
new file mode 100644
index 0000000..8922ffa
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_AudioPopUp.xml
@@ -0,0 +1,47 @@
+
+{{XML()}}{{
+{{SET(partID:{{VAL(MediaContainer/Video/Media/Part/id)}})}}
+{{SET(SelectedFound:false)}}
+
+
+ Audio tracks:
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"=="2")}})}}{{
+ {{IF({{VAL(selected)}})}}{{
+ {{SET(SelectedFound:true)}}
+
+ }}
+ {{IF(!{{VAL(selected)}})}}{{
+ {{IF(!{{VAL(default)}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"=="2")}})}}{{
+ {{IF(!{{VAL(selected)}})}}{{
+ {{IF({{VAL(default)}})}}{{
+ {{IF({{CHK("{{GET(SelectedFound)}}"=="true")}})}}{{
+
+ }}
+ {{IF({{CHK("{{GET(SelectedFound)}}"=="false")}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+ }}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Description.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Description.xml
new file mode 100755
index 0000000..f4b09bf
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Description.xml
@@ -0,0 +1,30 @@
+
+
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Directory.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Directory.xml
new file mode 100755
index 0000000..4a35316
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Directory.xml
@@ -0,0 +1,52 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+
+
+
+
+}}
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Episode.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Episode.xml
new file mode 100755
index 0000000..428ccc3
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Episode.xml
@@ -0,0 +1,192 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+ {{IF({{CHK("{{SETTING(themeMusic)}}"=="On")}})}}{{
+
+ }}
+ {{IF({{CHK("{{SETTING(tvshowFanart)}}"=="Show")}})}}{{
+
+ }}
+
+
+
+
+
+
+
+
+ {{IF({{CHK("{{SETTING(themeTitle)}}"=="Text")}})}}{{}}
+ {{IF({{CHK("{{SETTING(themeTitle)}}"=="Banner")}})}}{{}}
+
+
+ {{XML(/library/metadata/{{VAL(MediaContainer/grandparentRatingKey)}}/children)}}{{
+
+
+
+ }}
+
+
+
+ {{SET(last:0)}}
+ {{SET(lastEpisode:1)}}
+ {{COPY(MediaContainer/Video)}}{{
+ {{IF({{CHK("{{GET(last)}}"=="0")}})}}{{
+ {{IF(!{{VAL(viewCount:0)}})}}{{
+ {{SET(last:{{VAL(key)}})}}
+ {{SET(lastEpisode:{{VAL(index)}})}}
+ }}
+ }}
+ }}
+
+
+
+
+ Play Season
+
+
+
+
+ Continue Season
+
+
+
+
+ Go to Show
+
+
+
+
+
+
+
+ {{SET(parentIndex:{{VAL(MediaContainer/parentIndex:0)}})}}
+ {{SET(gpIndex:{{VAL(MediaContainer/grandparentRatingKey)}})}}
+
+
+ {{VAL(MediaContainer/size)}} Episode(s)
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+
+
+
+ {{IF({{VAL(viewOffset)}})}}{{
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+ }}
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{IF({{CHK("{{VAL(Media/videoResolution)}}"=="1080")}})}}{{1080p }}
+ {{IF({{CHK("{{VAL(Media/videoResolution)}}"=="720")}})}}{{720p }}
+ {{IF({{CHK("{{VAL(Media/videoResolution)}}"=="2k")}})}}{{2K }}
+ {{IF({{CHK("{{VAL(Media/videoResolution)}}"=="4k")}})}}{{4K }}
+ {{IF({{CHK("{{VAL(Media/videoResolution)}}"=="sd")}})}}{{SD }}
+
+ {{IF({{CHK("{{VAL(Media/audioCodec)}}"=="aac")}})}}{{AAC }}
+ {{IF({{CHK("{{VAL(Media/audioCodec)}}"=="ac3")}})}}{{AC3 }}
+ {{IF({{CHK("{{VAL(Media/audioCodec)}}"=="asf")}})}}{{ASF }}
+ {{IF({{CHK("{{VAL(Media/audioCodec)}}"=="dca")}})}}{{DTS }}
+ {{IF({{CHK("{{VAL(Media/audioCodec)}}"=="mp2")}})}}{{MPEG }}
+ {{IF({{CHK("{{VAL(Media/audioCodec)}}"=="mp3")}})}}{{MP3 }}
+ {{IF({{CHK("{{VAL(Media/audioCodec)}}"=="wmav2")}})}}{{WMA }}
+
+ {{IF({{CHK("{{VAL(Media/audioChannels)}}"=="1")}})}}{{1.0}}
+ {{IF({{CHK("{{VAL(Media/audioChannels)}}"=="2")}})}}{{2.0}}
+ {{IF({{CHK("{{VAL(Media/audioChannels)}}"=="6")}})}}{{5.1}}
+ {{IF({{CHK("{{VAL(Media/audioChannels)}}"=="8")}})}}{{7.1}}
+
+
+
+
+
+
+ }}
+
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_EpisodeContext.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_EpisodeContext.xml
new file mode 100755
index 0000000..40029b8
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_EpisodeContext.xml
@@ -0,0 +1,49 @@
+
+
+{{XML()}}{{
+
+
+
+
+
+
+
+{{SET(showMarkWatched:false)}}
+{{SET(showMarkUnwatched:false)}}
+{{IF({{VAL(MediaContainer/Video/viewOffset:0)}})}}{{
+ {{SET(showMarkWatched:true)}}
+ {{SET(showMarkUnwatched:true)}}
+}}
+{{IF({{VAL(MediaContainer/Video/viewCount:0)}})}}{{
+ {{SET(showMarkUnwatched:true)}}
+}}
+{{IF(!{{VAL(MediaContainer/Video/viewCount:0)}})}}{{
+ {{SET(showMarkWatched:true)}}
+}}
+{{IF({{GET(showMarkWatched)}})}}{{
+
+}}
+{{IF({{GET(showMarkUnwatched)}})}}{{
+
+}}
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_EpisodeDescription.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_EpisodeDescription.xml
new file mode 100644
index 0000000..fc3ac8e
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_EpisodeDescription.xml
@@ -0,0 +1,25 @@
+
+
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Filters.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Filters.xml
new file mode 100755
index 0000000..957d85f
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Filters.xml
@@ -0,0 +1,57 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+ {{VAL(MediaContainer/title1)}}
+ {{COPY(MediaContainer/Directory)}}{{
+ {{IF({{VAL(prompt)}})}}{{
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{VAL(prompt)}})}}{{
+ {{IF({{CHK("{{VAL(key:)}}"=="folder")}})}}{{
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{CHK("{{VAL(key:)}}"=="folder")}})}}{{
+ {{IF({{CHK("{{VAL(secondary:)}}"=="1")}})}}{{
+ {{SET(noItems:false)}}
+
+ }}
+ {{IF(!{{CHK("{{VAL(secondary:)}}"=="1")}})}}{{
+ {{SET(noItems:false)}}
+
+ }}
+ }}
+ }}
+ }}
+}}
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Grid.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Grid.xml
new file mode 100755
index 0000000..588f0c1
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Grid.xml
@@ -0,0 +1,96 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Search
+
+
+
+ Reload
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+ {{VAL(year:)}}
+
+ }}
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+
+ }}
+
+
+ }}
+
+
+
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_MorePopUp.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_MorePopUp.xml
new file mode 100644
index 0000000..45be4af
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_MorePopUp.xml
@@ -0,0 +1,19 @@
+
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_OnDeck.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_OnDeck.xml
new file mode 100755
index 0000000..604aa22
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_OnDeck.xml
@@ -0,0 +1,137 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Filters
+
+
+
+ Search
+
+
+
+ Reload
+
+
+
+ {{XML(/hubs/sections/{{VAL(MediaContainer/librarySectionID)}}/?count=15&excludeFields=summary)}}{{
+ {{IFNODE(MediaContainer/Hub)}}{{
+ {{SET(noItems:false)}}
+
+ {{COPY(MediaContainer/Hub)}}{{
+ {{IF({{CHK("{{VAL(size)}}">"0")}})}}{{
+ {{IF(!{{CHK("{{VAL(hubIdentifier)}}"="tv.inprogress")}})}}{{
+
+
+
+ {{IFNODE(Directory)}}{{
+ {{COPY(Directory)}}{{
+ {{IF({{CHK("{{VAL(type:)}}"=="show")}})}}{{
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+
+ }}
+ {{IF({{CHK("{{VAL(type:)}}"=="season")}})}}{{
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+
+ }}
+ }}
+ }}
+ {{IFNODE(Video)}}{{
+ {{COPY(Video)}}{{
+
+
+
+
+ {{IF({{VAL(viewOffset)}})}}{{
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+ }}
+ }}
+
+
+ {{TEXT(S)}}{{VAL(parentIndex)}} • {{TEXT(E)}}{{VAL(index)}}
+
+ }}
+ }}
+
+
+ }}
+ }}
+ }}
+
+ }}
+ }}
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_PrePlay.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_PrePlay.xml
new file mode 100755
index 0000000..e764b71
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_PrePlay.xml
@@ -0,0 +1,225 @@
+
+
+{{XML()}}{{
+{{SET(sectionID:{{VAL(MediaContainer/librarySectionID)}})}}
+{{SET(AudioIsDefault:true)}}
+{{SET(SubsIsDefault:true)}}
+
+
+
+
+
+
+
+ {{IF({{CHK("{{SETTING(themeMusic)}}"=="On")}})}}{{
+
+ }}
+ {{IF({{CHK("{{SETTING(tvshowFanart)}}"=="Show")}})}}{{
+
+ }}
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Video/Director)}}{{
+
+ }}
+
+
+
+ {{COPY(MediaContainer/Video/Writer)}}{{
+
+ }}
+
+
+
+
+
+
+
+ Season {{VAL(MediaContainer/Video/parentIndex)}}, Episode {{VAL(MediaContainer/Video/index)}}
+
+
+
+
+
+ {{DURATION({{VAL(MediaContainer/Video/duration)}})}}
+
+
+
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="1080")}})}}{{1080p}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="720")}})}}{{720p}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="2k")}})}}{{2K}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="4k")}})}}{{4K}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/videoResolution)}}"=="sd")}})}}{{SD}}
+
+
+
+
+
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="aac")}})}}{{AAC}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="ac3")}})}}{{AC3}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="asf")}})}}{{ASF}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="dca")}})}}{{DTS}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="mp2")}})}}{{MPEG}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="mp3")}})}}{{MP3}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioCodec)}}"=="wmav2")}})}}{{WMA}}
+
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioChannels)}}"=="1")}})}}{{1.0}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioChannels)}}"=="2")}})}}{{2.0}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioChannels)}}"=="6")}})}}{{5.1}}
+ {{IF({{CHK("{{VAL(MediaContainer/Video/Media/audioChannels)}}"=="8")}})}}{{7.1}}
+
+
+
+
+
+
+
+
+ {{IF(!{{VAL(MediaContainer/Video/viewOffset)}})}}{{
+
+
+ {{TEXT(Play)}}
+
+ }}
+ {{IF({{VAL(MediaContainer/Video/viewOffset)}})}}{{
+
+
+ {{TEXT(Resume)}}
+
+ }}
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"="2")}})}}{{
+ {{IF({{CHK("{{VAL(selected)}}"="1")}})}}{{
+ {{SET(AudioIsDefault:false)}}
+
+
+
+
+ }}
+ }}
+ }}
+ {{IF({{GET(AudioIsDefault)}})}}{{
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"="2")}})}}{{
+ {{IF({{CHK("{{VAL(default)}}"="1")}})}}{{
+
+
+
+
+ }}
+ }}
+ }}
+ }}
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"="3")}})}}{{
+ {{IF({{CHK("{{VAL(selected)}}"="1")}})}}{{
+ {{SET(SubsIsDefault:false)}}
+
+
+
+
+ }}
+ }}
+ }}
+ {{IF({{GET(SubsIsDefault)}})}}{{
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"="3")}})}}{{
+ {{IF({{CHK("{{VAL(default)}}"="1")}})}}{{
+
+
+
+
+ }}
+ }}
+ }}
+ }}
+
+
+
+ {{TEXT(More)}}
+
+
+
+
+
+
+
+
+
+ {{XML(/library/metadata/{{VAL(MediaContainer/Video/parentRatingKey)}}/children)}}{{
+ {{SET(season:{{VAL(MediaContainer/parentIndex:)}})}}
+
+
+ {{TEXT(All Episodes)}}
+
+
+ {{COPY(MediaContainer/Video)}}{{
+ {{SET(noItems:false)}}
+
+
+
+ {{IF({{VAL(viewOffset)}})}}{{
+
+ }}
+ {{IF(!{{VAL(viewOffset)}})}}{{
+ {{IF(!{{VAL(viewCount)}})}}{{
+
+ }}
+ }}
+
+
+
+ }}
+
+
+ }}
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_PrePlayDescription.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_PrePlayDescription.xml
new file mode 100755
index 0000000..da3dcf4
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_PrePlayDescription.xml
@@ -0,0 +1,30 @@
+
+
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Season.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Season.xml
new file mode 100755
index 0000000..4094c39
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Season.xml
@@ -0,0 +1,178 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+ {{IF({{CHK("{{SETTING(themeMusic)}}"=="On")}})}}{{
+
+ }}
+ {{IF({{CHK("{{SETTING(tvshowFanart)}}"=="Show")}})}}{{
+
+ }}
+
+
+
+
+
+
+ {{XML(/library/metadata/{{VAL(MediaContainer/key)}})}}{{
+
+ }}
+
+
+
+
+ {{XML(/library/metadata/{{VAL(MediaContainer/key)}})}}{{
+ {{COPY(MediaContainer/Directory/Role)}}{{
+
+ }}
+ }}
+
+
+
+
+
+ {{IF({{CHK("{{SETTING(themeTitle)}}"=="Text")}})}}{{}}
+ {{IF({{CHK("{{SETTING(themeTitle)}}"=="Banner")}})}}{{}}
+
+
+ {{XML(/library/metadata/{{VAL(MediaContainer/key)}})}}{{
+ {{VAL(MediaContainer/Directory/year)}}
+ {{COPY(MediaContainer/Directory/Genre)}}{{
+
+ }}
+ {{IF({{CHK("{{VAL(MediaContainer/Directory/contentRating)}}"=="TV-14")}})}}{{TV-14}}
+ {{IF({{CHK("{{VAL(MediaContainer/Directory/contentRating)}}"=="TV-Y")}})}}{{TV-Y}}
+ {{IF({{CHK("{{VAL(MediaContainer/Directory/contentRating)}}"=="TV-Y7")}})}}{{TV-Y7}}
+ {{IF({{CHK("{{VAL(MediaContainer/Directory/contentRating)}}"=="TV-Y7VF")}})}}{{TV-Y7VF}}
+ {{IF({{CHK("{{VAL(MediaContainer/Directory/contentRating)}}"=="TV-G")}})}}{{TV-G}}
+ {{IF({{CHK("{{VAL(MediaContainer/Directory/contentRating)}}"=="TV-PG")}})}}{{TV-PG}}
+ {{IF({{CHK("{{VAL(MediaContainer/Directory/contentRating)}}"=="TV-MA")}})}}{{TV-MA}}
+ }}
+
+
+
+
+
+
+
+
+
+
+
+ Play Show
+
+
+
+ Shuffle Show
+
+
+
+ Watch Status
+
+
+
+
+
+
+
+ {{XML(/library/metadata/{{VAL(MediaContainer/key)}})}}{{
+ {{VAL(MediaContainer/Directory/childCount)}} Season(s)
+ }}
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+ {{IF(!{{CHK("{{VAL(title)}}"=="All episodes")}})}}{{
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+ }}
+ }}
+
+
+
+ {{SET(sectionID:{{VAL(MediaContainer/librarySectionID)}})}}
+ {{XML(/library/metadata/{{VAL(MediaContainer/key)}})}}{{
+
+
+
+ {{COPY(MediaContainer/Directory/Role)}}
+ {{
+
+
+
+
+
+ }}
+
+
+ }}
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_SeasonPopup.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_SeasonPopup.xml
new file mode 100755
index 0000000..c72ff77
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_SeasonPopup.xml
@@ -0,0 +1,77 @@
+
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+ {{IF({{CHK("{{SETTING(themeMusic)}}"=="On")}})}}{{
+
+ }}
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+ {{SET(noItems:false)}}
+ {{IF(!{{CHK("{{VAL(title)}}"=="All episodes")}})}}{{
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+
+ }}
+
+ {{VAL(leafCount)}} {{TEXT(Episode(s))}}
+
+
+ }}
+ }}
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Secondary.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Secondary.xml
new file mode 100755
index 0000000..268ecad
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_Secondary.xml
@@ -0,0 +1,66 @@
+
+
+{{XML()}}
+{{
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+
+ {{XML({{VAL(key)}})}}{{
+
+
+
+
+ {{COPY(MediaContainer/Directory)}}{{
+
+
+ {{IF(!{{CHK("{{VAL(leafCount)}}"="{{VAL(viewedLeafCount)}}")}})}}{{
+
+
+ {{EVAL({{VAL(leafCount)}}-{{VAL(viewedLeafCount)}})}}
+
+ }}
+
+
+ }}
+
+
+
+ }}
+
+ }}
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/TVShow_SubsPopUp.xml b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_SubsPopUp.xml
new file mode 100644
index 0000000..c3e4f3a
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/TVShow_SubsPopUp.xml
@@ -0,0 +1,47 @@
+
+{{XML()}}{{
+{{SET(partID:{{VAL(MediaContainer/Video/Media/Part/id)}})}}
+{{SET(SelectedFound:false)}}
+
+
+ Available subtitles:
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"=="3")}})}}{{
+ {{IF({{VAL(selected)}})}}{{
+ {{SET(SelectedFound:true)}}
+
+ }}
+ {{IF(!{{VAL(selected)}})}}{{
+ {{IF(!{{VAL(default)}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+
+ {{COPY(MediaContainer/Video/Media/Part/Stream)}}{{
+ {{IF({{CHK("{{VAL(streamType:)}}"=="3")}})}}{{
+ {{IF(!{{VAL(selected)}})}}{{
+ {{IF({{VAL(default)}})}}{{
+ {{IF({{CHK("{{GET(SelectedFound)}}"=="true")}})}}{{
+
+ }}
+ {{IF({{CHK("{{GET(SelectedFound)}}"=="false")}})}}{{
+
+ }}
+ }}
+ }}
+ }}
+ }}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Videos_List.xml b/PlexConnectApp/TVMLTemplates/Revenant/Videos_List.xml
new file mode 100755
index 0000000..31daf43
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Videos_List.xml
@@ -0,0 +1,119 @@
+
+{{CUT({{GET(noItems)}})}}{{
+{{SET(noItems:true)}}
+{{XML()}}{{
+
+
+
+
+
+
+
+
+
+
+
+
+ Play all
+
+
+
+ Shuffle all
+
+
+
+
+
+
+
+
+ {{TEXT(Shuffle all)}}
+
+
+
+
+
+
+
+{{COPY(MediaContainer/Directory)}}{{
+{{SET(noItems:false)}}
+
+
+
+
+
+}}
+
+
+
+{{COPY(MediaContainer/Video)}}{{
+{{SET(noItems:false)}}
+
+
+
+ {{DURATION_HMS({{VAL(duration)}})}}
+ {{IF(!{{VAL(viewCount)}})}}{{
+ {{IF(!{{VAL(viewOffset)}})}}{{
+
+ }}
+ {{IF({{VAL(viewOffset)}})}}{{
+
+ }}
+ }}
+ {{IF({{VAL(viewCount)}})}}{{
+
+ }}
+
+
+
+
+
+
+}}
+
+
+
+
+
+}}
+}}
+
+{{IF({{GET(noItems)}})}}
+{{
+
+
+ PlexConnect
+ {{TEXT(Plex Media Server: No Items Available)}}
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/Videos_ResumePopUp.xml b/PlexConnectApp/TVMLTemplates/Revenant/Videos_ResumePopUp.xml
new file mode 100755
index 0000000..b0bfebb
--- /dev/null
+++ b/PlexConnectApp/TVMLTemplates/Revenant/Videos_ResumePopUp.xml
@@ -0,0 +1,13 @@
+
+{{XML()}}{{
+
+
+
+
+
+
+}}
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/RT/certified.png b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/certified.png
new file mode 100644
index 0000000..54c3665
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/certified.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/RT/plus.png b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/plus.png
new file mode 100644
index 0000000..156fe68
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/plus.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/RT/ripe.png b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/ripe.png
new file mode 100644
index 0000000..f93de1f
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/ripe.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/RT/rotten.png b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/rotten.png
new file mode 100644
index 0000000..caaa7f3
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/rotten.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/RT/spilled.png b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/spilled.png
new file mode 100644
index 0000000..c2c999f
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/spilled.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/RT/star.png b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/star.png
new file mode 100644
index 0000000..c9629e7
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/star.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/RT/upright.png b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/upright.png
new file mode 100644
index 0000000..83685e7
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/RT/upright.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/ServerIcon.png b/PlexConnectApp/TVMLTemplates/Revenant/images/ServerIcon.png
new file mode 100644
index 0000000..457185b
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/ServerIcon.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/ServerIcon2.png b/PlexConnectApp/TVMLTemplates/Revenant/images/ServerIcon2.png
new file mode 100755
index 0000000..ed79baf
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/ServerIcon2.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Artist.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Artist.png
new file mode 100755
index 0000000..a23c806
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Artist.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Audio.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Audio.png
new file mode 100755
index 0000000..4c3f269
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Audio.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Eye.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Eye.png
new file mode 100755
index 0000000..cda80cc
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Eye.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Favorites.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Favorites.png
new file mode 100755
index 0000000..ce03867
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Favorites.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Library.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Library.png
new file mode 100755
index 0000000..0ec5643
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Library.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/MarkWatched.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/MarkWatched.png
new file mode 100755
index 0000000..574af39
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/MarkWatched.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/More.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/More.png
new file mode 100755
index 0000000..a2a447c
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/More.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/MusicVideo.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/MusicVideo.png
new file mode 100755
index 0000000..5aa1bf2
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/MusicVideo.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Pause.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Pause.png
new file mode 100755
index 0000000..0c94d8b
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Pause.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Play.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Play.png
new file mode 100755
index 0000000..ecd3e4b
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Play.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlayAll.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlayAll.png
new file mode 100755
index 0000000..ad2b62c
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlayAll.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlayResume.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlayResume.png
new file mode 100644
index 0000000..4f3cbb0
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlayResume.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Playing.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Playing.png
new file mode 100755
index 0000000..5f99c26
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Playing.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Playlist.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Playlist.png
new file mode 100755
index 0000000..26b08e8
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Playlist.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlaylistAudio.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlaylistAudio.png
new file mode 100755
index 0000000..a596097
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/PlaylistAudio.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Reload.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Reload.png
new file mode 100755
index 0000000..9f92ca6
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Reload.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Search.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Search.png
new file mode 100755
index 0000000..099015a
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Search.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Server.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Server.png
new file mode 100755
index 0000000..c902047
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Server.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Settings.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Settings.png
new file mode 100755
index 0000000..12b642d
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Settings.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Shuffle.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Shuffle.png
new file mode 100755
index 0000000..ab3a237
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Shuffle.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Star.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Star.png
new file mode 100755
index 0000000..a57dd9d
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Star.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Subtitles.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Subtitles.png
new file mode 100755
index 0000000..402a7ac
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Subtitles.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Trailer.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Trailer.png
new file mode 100755
index 0000000..c37fc84
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/Trailer.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/User.png b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/User.png
new file mode 100644
index 0000000..0f79d09
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/buttons/User.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/defaultIcon.png b/PlexConnectApp/TVMLTemplates/Revenant/images/defaultIcon.png
new file mode 100644
index 0000000..9dff492
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/defaultIcon.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/flags/unwatched.png b/PlexConnectApp/TVMLTemplates/Revenant/images/flags/unwatched.png
new file mode 100644
index 0000000..5bb62d2
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/flags/unwatched.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/flags/unwatched2.png b/PlexConnectApp/TVMLTemplates/Revenant/images/flags/unwatched2.png
new file mode 100644
index 0000000..cbc1ba1
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/flags/unwatched2.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/flags/watching.png b/PlexConnectApp/TVMLTemplates/Revenant/images/flags/watching.png
new file mode 100644
index 0000000..cfac4a8
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/flags/watching.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/flags/watching2.png b/PlexConnectApp/TVMLTemplates/Revenant/images/flags/watching2.png
new file mode 100644
index 0000000..09190cf
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/flags/watching2.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/folder.png b/PlexConnectApp/TVMLTemplates/Revenant/images/folder.png
new file mode 100644
index 0000000..23bd95a
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/folder.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/servers/Local.png b/PlexConnectApp/TVMLTemplates/Revenant/images/servers/Local.png
new file mode 100755
index 0000000..a3fe7d2
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/servers/Local.png differ
diff --git a/PlexConnectApp/TVMLTemplates/Revenant/images/servers/Remote.png b/PlexConnectApp/TVMLTemplates/Revenant/images/servers/Remote.png
new file mode 100755
index 0000000..9d37898
Binary files /dev/null and b/PlexConnectApp/TVMLTemplates/Revenant/images/servers/Remote.png differ
diff --git a/PlexConnectApp/Utilities.swift b/PlexConnectApp/Utilities.swift
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/ViewController.swift b/PlexConnectApp/ViewController.swift
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/XMLConverter.swift b/PlexConnectApp/XMLConverter.swift
old mode 100644
new mode 100755
index 6ae3d53..d4d6a33
--- a/PlexConnectApp/XMLConverter.swift
+++ b/PlexConnectApp/XMLConverter.swift
@@ -39,11 +39,16 @@ class cXmlConverter {
// jump table to commands processing attributes: VAL, VIDEOURL, ...
processAttrib = [
"VAL": processVAL!,
+ "ESCVAL": processESCVAL!,
"TABLE": processTABLE!,
"EVAL": processEVAL!,
"DURATION": processDURATION!,
+ "DURATION_HM": processDURATION_HM!,
"DURATION_HMS": processDURATION_HMS!,
"SEASONEPISODE": processSEASONEPISODE!,
+ "EP_INDEX": processEP_INDEX!,
+ "ACTOR_LN": processACTOR_LN!,
+ "UPPERCASE": processUPPERCASE!,
"CHK": processCHK!,
"PMSCNT": processPMSCNT!,
"PMSID": processPMSID!,
@@ -57,6 +62,10 @@ class cXmlConverter {
"AUDIOURL": processAUDIOURL!,
"PHOTOURL": processPHOTOURL!,
"IMAGEURL": processIMAGEURL!,
+ "IMAGE_T": processIMAGE_T!,
+ "IMAGEHTTP": processIMAGEHTTP!,
+ "RTBADGE": processRTBADGE!,
+ "IMAGEPARADE": processIMAGEPARADE!,
"TEXT": processTEXT!,
"SETTING": processSETTING!,
"CUSTOMSETTING": processCUSTOMSETTING!,
@@ -445,6 +454,50 @@ class cXmlConverter {
return res
}
+ var processDURATION_HM: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(":")
+ var hours: Int = 0, minutes: Int = 0, seconds: Int = 0
+ if let duration = Int(_self.getParam(XML, par: &par)) { // duration in ms
+ var sec: Int
+ sec = duration / 1000 // duration in sec
+ hours = sec / 60/60
+ sec = sec - hours * 60*60 // duration (after hours) in sec
+ minutes = sec / 60
+ sec = sec - minutes * 60 // duration (after hours/minutes) in sec
+ seconds = sec
+ }
+ var res: String
+ if (hours>0) {
+ res = String("\(hours) hr \(minutes) min")
+ } else {
+ res = String("\(minutes) min")
+ }
+ return res
+ }
+
+ var processACTOR_LN: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(" ")
+ let firstName = String(_self.getParam(XML, par: &par))
+ let lastName = String(_self.getParam(XML, par: &par))
+ let res = String (lastName)
+ return res
+
+ }
+
+ var processUPPERCASE: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(":")
+ let label = String(_self.getParam(XML, par: &par))
+ let res = label.uppercaseString
+ return res
+
+ }
+
var processSEASONEPISODE: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
_self, XML, _par in
@@ -455,6 +508,21 @@ class cXmlConverter {
return res
}
+ var processEP_INDEX: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(":")
+ let season = String(_self.getParam(XML, par: &par))
+ let episode = String(_self.getParam(XML, par: &par))
+ if !(season=="") {
+ let res = String(season + "." + episode)
+ return res
+ } else {
+ let res = String(episode)
+ return res
+ }
+ }
+
var processPATH: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
_self, XML, _par in
@@ -743,6 +811,143 @@ class cXmlConverter {
}
}
+ var processIMAGE_T: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(":")
+
+ // sanity check
+ if _self.pmsId == nil {
+ return "[[IMAGEURL - pmsId not initialised]]"
+ }
+
+ let key = _self.getKey(XML, par: &par)
+ if key.hasPrefix("http://") || key.hasPrefix("https://") { // external address, eg. channels - keep
+ return key
+ } else if (key != "") {
+ var res: String
+ let key = "/photo/:/transcode?height=400&width=400&url=" + key
+ res = getPmsUrl(key, pmsId: _self.pmsId!, pmsPath: _self.pmsPath!) // todo: pmsId, pmsPath optional?
+ // XML safe?
+ res = res.stringByReplacingOccurrencesOfString("&", withString: "&") // must be first
+ res = res.stringByReplacingOccurrencesOfString("<", withString: "<")
+ res = res.stringByReplacingOccurrencesOfString(">", withString: ">")
+ res = res.stringByReplacingOccurrencesOfString("'", withString: "'")
+ res = res.stringByReplacingOccurrencesOfString("\"", withString: """)
+
+ return res
+ } else {
+ let res = getResourceUrl("missing-image", ext: "png", dir: "Images")
+ return res
+ }
+ }
+
+ var processESCVAL: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(":")
+ var res: String
+
+ res = _self.getKey(XML, par: &par)
+ res = res.stringByReplacingOccurrencesOfString("&", withString: "&") // must be first
+ res = res.stringByReplacingOccurrencesOfString("<", withString: "<")
+ res = res.stringByReplacingOccurrencesOfString(">", withString: ">")
+ res = res.stringByReplacingOccurrencesOfString("'", withString: "'")
+ res = res.stringByReplacingOccurrencesOfString("\"", withString: """)
+
+ return res
+ }
+
+ var processIMAGEHTTP: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(" ")
+
+ // sanity check
+ if _self.pmsId == nil {
+ return "[[IMAGEURL - pmsId not initialised]]"
+ }
+
+ let key = _self.getKey(XML, par: &par)
+ if (key != "") {
+ var res: String
+ res = key
+ // res = getPmsUrl(key, pmsId: _self.pmsId!, pmsPath: _self.pmsPath!) // todo: pmsId, pmsPath optional?
+ // XML safe?
+ res = res.stringByReplacingOccurrencesOfString("&", withString: "&") // must be first
+ res = res.stringByReplacingOccurrencesOfString("<", withString: "<")
+ res = res.stringByReplacingOccurrencesOfString(">", withString: ">")
+ res = res.stringByReplacingOccurrencesOfString("'", withString: "'")
+ res = res.stringByReplacingOccurrencesOfString("\"", withString: """)
+
+ return res
+ } else {
+ let res = getResourceUrl("missing-image", ext: "png", dir: "Images")
+ return res
+ }
+ }
+
+ var processRTBADGE: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(" ")
+ var res : String
+ // sanity check
+ if _self.pmsId == nil {
+ return "[[IMAGEURL - pmsId not initialised]]"
+ }
+
+ let key: String = _self.getKey(XML, par: &par)
+ if (key != "") {
+ let res_array = key.componentsSeparatedByString(".")
+ res = res_array[2]
+ if res == "rotten" {
+ res = "splat"
+ return res
+ } else if res == "ripe" {
+ res = "fresh"
+ return res
+ }
+
+ return res
+
+ } else {
+ res = key
+ return res
+ }
+ }
+
+ var processIMAGEPARADE: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
+ _self, XML, _par in
+
+ var par = _par.componentsSeparatedByString(" ")
+
+ // sanity check
+ if _self.pmsId == nil {
+ return "[[IMAGEURL - pmsId not initialised]]"
+ }
+
+ let key = _self.getKey(XML, par: &par)
+ if (key != "") {
+ var res: String
+ res = key
+ res = getPmsUrl(key, pmsId: _self.pmsId!, pmsPath: _self.pmsPath!) // todo: pmsId, pmsPath optional?
+
+ // XML safe?
+ res = res.stringByReplacingOccurrencesOfString("/art/", withString: "/thumb/") // must be first
+ res = res.stringByReplacingOccurrencesOfString("&", withString: "&") // must be first
+ res = res.stringByReplacingOccurrencesOfString("<", withString: "<")
+ res = res.stringByReplacingOccurrencesOfString(">", withString: ">")
+ res = res.stringByReplacingOccurrencesOfString("'", withString: "'")
+ res = res.stringByReplacingOccurrencesOfString("\"", withString: """)
+
+ return res
+ } else {
+ let res = getResourceUrl("missing-image", ext: "png", dir: "Images")
+ return res
+ }
+ }
+
var processEVAL: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
_self, XML, _par in
@@ -751,7 +956,12 @@ class cXmlConverter {
let expr = NSExpression(format: param)
let res = expr.expressionValueWithObject(nil, context: nil)
- return String(res)
+ var test:String = ""
+ test = String(res)
+ test = test.stringByReplacingOccurrencesOfString("Optional(", withString: "")
+ test = test.stringByReplacingOccurrencesOfString(")", withString: "")
+ // Bug return String(res) liefert String mit Optional als Text im String
+ return test
}
var processCHK: ((_self: cXmlConverter,XML: XMLIndexer?, par: String) -> String)? = {
diff --git a/PlexConnectApp/js/App.js b/PlexConnectApp/js/App.js
old mode 100644
new mode 100755
index 3fda535..a5c6d46
--- a/PlexConnectApp/js/App.js
+++ b/PlexConnectApp/js/App.js
@@ -23,7 +23,7 @@ var console = {
App.onLaunch = function(options) {
-
+
var javascriptFiles = [
`${options.BASEURL}/js/Utilities.js`,
`${options.BASEURL}/js/Presenter.js`,
@@ -34,7 +34,7 @@ App.onLaunch = function(options) {
`${options.BASEURL}/js/MyPlex.js`,
`${options.BASEURL}/js/Search.js`
];
-
+
evaluateScripts(javascriptFiles, function(success) {
if(success) {
console.log(options);
@@ -48,12 +48,12 @@ App.onLaunch = function(options) {
App.onResume = function() {
console.log('onResume');
- Presenter.load('Main','','');
+ //Presenter.load('Main','','');
}
App.onSuspend = function() {
console.log('onSuspend');
- navigationDocument.clear();
+ //navigationDocument.clear();
}
App.onExit = function() {
@@ -72,4 +72,4 @@ var createAlert = function(title, description) {
var parser = new DOMParser();
var alertDoc = parser.parseFromString(alertString, "application/xml");
return alertDoc;
-}
\ No newline at end of file
+}
diff --git a/PlexConnectApp/js/AudioPlayer.js b/PlexConnectApp/js/AudioPlayer.js
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/js/MyPlex.js b/PlexConnectApp/js/MyPlex.js
old mode 100644
new mode 100755
index 02caa39..25f4bbf
--- a/PlexConnectApp/js/MyPlex.js
+++ b/PlexConnectApp/js/MyPlex.js
@@ -27,6 +27,7 @@ discover = function(event) {
var func = elem.getAttribute('onSuccess');
doc.addEventListener("unload", function() { eval(func) });
navigationDocument.popDocument();
+
}
diff --git a/PlexConnectApp/js/PhotoPresenter.js b/PlexConnectApp/js/PhotoPresenter.js
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/js/Presenter.js b/PlexConnectApp/js/Presenter.js
old mode 100644
new mode 100755
index d277d06..400410b
--- a/PlexConnectApp/js/Presenter.js
+++ b/PlexConnectApp/js/Presenter.js
@@ -10,7 +10,7 @@
var Presenter = {
-
+
makeDocument: function(resource) {
if (!Presenter.parser) {
Presenter.parser = new DOMParser();
@@ -31,36 +31,78 @@ modalDialogPresenter: function(xml) {
*/
setupViewDocument: function(view, pmsId, pmsPath) {
console.log("load");
-
+
var docString = swiftInterface.getViewIdPath(view, pmsId, pmsPath);
var parser = new DOMParser();
var doc = parser.parseFromString(docString, "application/xml");
-
+
// events: https://developer.apple.com/library/tvos/documentation/TVMLKit/Reference/TVViewElement_Ref/index.html#//apple_ref/c/tdef/TVElementEventType
doc.addEventListener("select", Presenter.onSelect.bind(Presenter));
doc.addEventListener("holdselect", Presenter.onHoldSelect.bind(Presenter));
doc.addEventListener("play", Presenter.onPlay.bind(Presenter));
doc.addEventListener("highlight", Presenter.onHighlight.bind(Presenter));
doc.addEventListener("load", Presenter.onLoad.bind(Presenter)); // setup search for char entered
-
- // store address in DOM - eg for later page refresh
- doc.source = {
- view: view,
- pmsId: pmsId,
- pmsPath: pmsPath,
- };
-
+ // store address in DOM - eg for later page refresh
+ doc.source = {
+ view: view,
+ pmsId: pmsId,
+ pmsPath: pmsPath,
+ };
+
return doc
},
load: function(view, pmsId, pmsPath) {
- var loadingDoc = createSpinner("");
+ var loadingDoc = createSpinner("Loading...");
loadingDoc.addEventListener("load", function() {
var doc = Presenter.setupViewDocument(view, pmsId, pmsPath);
- navigationDocument.replaceDocument(doc, loadingDoc);
+ navigationDocument.replaceDocument(doc, loadingDoc);
});
navigationDocument.pushDocument(loadingDoc);
//navigationDocument.dismissModal(); // just in case?! // todo: if (isModal)...?
+
+
+},
+
+loadView: function(view, pmsId, pmsPath) {
+ var doc = Presenter.setupViewDocument(view, pmsId, pmsPath);
+ navigationDocument.pushDocument(doc);
+
+
+},
+
+loadArt: function(view, pmsId, pmsPath, artwork, title) {
+ var loadingDoc = createArtSpinner(title, artwork);
+ loadingDoc.addEventListener("load", function() {
+ var doc = Presenter.setupViewDocument(view, pmsId, pmsPath);
+ navigationDocument.replaceDocument(doc, loadingDoc);
+ });
+ navigationDocument.pushDocument(loadingDoc);
+ //navigationDocument.dismissModal(); // just in case?! // todo: if (isModal)...?
+
+
+},
+
+loadTitle: function(view, pmsId, pmsPath, title) {
+ var loadingDoc = createTitleSpinner(title);
+ loadingDoc.addEventListener("load", function() {
+ var doc = Presenter.setupViewDocument(view, pmsId, pmsPath);
+ navigationDocument.replaceDocument(doc, loadingDoc);
+ });
+ navigationDocument.pushDocument(loadingDoc);
+ //navigationDocument.dismissModal(); // just in case?! // todo: if (isModal)...?
+
+
+},
+
+
+loadPopup: function(view, pmsId, pmsPath) {
+ var currentDoc = navigationDocument.documents[navigationDocument.documents.length-1];
+
+ var doc = Presenter.setupViewDocument(view, pmsId, pmsPath);
+ navigationDocument.replaceDocument(doc, currentDoc);
+ navigationDocument.dismissModal();
+
},
loadAndSwap: function(view, pmsId, pmsPath) {
@@ -74,24 +116,26 @@ loadAndSwap: function(view, pmsId, pmsPath) {
// navigationDocument.dismissModal(); // just in case?! // todo: if (isModal)...?
},
+
+
close() {
navigationDocument.popDocument();
},
-
+
loadContext(view, pmsId, pmsPath) {
var doc = Presenter.setupViewDocument(view, pmsId, pmsPath);
navigationDocument.presentModal(doc);
},
-
+
closeContext() {
navigationDocument.dismissModal();
},
-
+
loadMenuContent: function(view, pmsId, pmsPath) {
console.log("loadMenuContent");
var elem = this.event.target; // todo: check event existing
var id = elem.getAttribute("id");
-
+
var feature = elem.parentNode.getFeature("MenuBarDocument");
if (feature) {
var currentDoc = feature.getDocument(elem);
@@ -116,16 +160,16 @@ loadParade: function(view, pmsId, pmsPath) {
if (elem.hasChildNodes()) { // related content already populated?
return;
}
-
+
// update view
var doc = Presenter.setupViewDocument(view, pmsId, pmsPath);
var elemNew = doc.getElementByTagName("relatedContent");
-
+
if (elem && elemNew) {
elem.innerHTML = elemNew.innerHTML;
}
},
-
+
// store event for downstream use
event: "",
@@ -145,12 +189,12 @@ onSelect: function(event) {
}
}
},
-
+
onHoldSelect: function(event) {
console.log("onHoldSelect "+event);
this.event = event;
var elem = event.target;
-
+
if (elem) {
var id = elem.getAttribute("id");
var onHoldSelect = elem.getAttribute("onHoldSelect"); // get onHoldSelect=...
@@ -162,7 +206,7 @@ onHoldSelect: function(event) {
}
}
},
-
+
onPlay: function(event) {
console.log("onPlay "+event);
this.event = event;
@@ -185,7 +229,7 @@ onHighlight: function(event) {
console.log("onHighlight "+event);
this.event = event;
var elem = event.target;
-
+
if (elem) {
var onHighlight = elem.getAttribute("onHighlight"); // get onHighlight=...
if (onHighlight) {
@@ -193,7 +237,7 @@ onHighlight: function(event) {
}
}
},
-
+
// grab keyboard changes for searchField
onLoad: function(event) {
var elem = event.target;
diff --git a/PlexConnectApp/js/Search.js b/PlexConnectApp/js/Search.js
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/js/Settings.js b/PlexConnectApp/js/Settings.js
old mode 100644
new mode 100755
diff --git a/PlexConnectApp/js/Utilities.js b/PlexConnectApp/js/Utilities.js
old mode 100644
new mode 100755
index 5d60442..149ef6e
--- a/PlexConnectApp/js/Utilities.js
+++ b/PlexConnectApp/js/Utilities.js
@@ -84,7 +84,7 @@ function shuffleArray(arr) {
arr[i] = arr[j];
arr[j] = temp;
}
-
+
return arr;
}
@@ -100,7 +100,13 @@ function loadPage(url)
req.send();
};
-
+// Send http PUT request - disregard response
+function putData(url)
+{
+ var req = new XMLHttpRequest();
+ req.open('PUT', url, true);
+ req.send();
+};
// prepare for localisation - currently just return string
function TEXT(textString) {
@@ -114,7 +120,21 @@ var createSpinner = function(title) {
- ${title}
+
+
+
+`
+ var parser = new DOMParser();
+ var doc = parser.parseFromString(docString, "application/xml");
+ return doc;
+}
+
+var createTitleSpinner = function(title) {
+ var docString = `
+
+
+
+
`
@@ -122,3 +142,23 @@ var createSpinner = function(title) {
var doc = parser.parseFromString(docString, "application/xml");
return doc;
}
+
+var createArtSpinner = function(title, art) {
+ var docString = `
+
+
+
+
+
+
+
+
+
+
+ `
+ var parser = new DOMParser();
+ var doc = parser.parseFromString(docString, "application/xml");
+ return doc;
+ }
diff --git a/PlexConnectApp/js/VideoPlayer.js b/PlexConnectApp/js/VideoPlayer.js
old mode 100644
new mode 100755