Compare commits
	
		
			609 Commits
		
	
	
		
			update-agg
			...
			9db95c4e6c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9db95c4e6c | |||
| 249807c935 | |||
| eec79b2dc5 | |||
| 464c013095 | |||
| e2f4995cad | |||
| a43b286e39 | |||
| 148f5362f0 | |||
| 4d01e9814d | |||
| b9e3e1f310 | |||
| b0da48c4fb | |||
| 1e53dc21ee | |||
| 5c5014339f | |||
| 84188a6066 | |||
| 7c7be319d1 | |||
| 79784faba1 | |||
| f3ea44755c | |||
| 9b6559559c | |||
| 2398216bf2 | |||
| d942b91d17 | |||
| 24d9b9225e | |||
| f6f6404302 | |||
| 4609af726b | |||
| c5919c90d0 | |||
| 605adc3293 | |||
| b40554d38d | |||
| 194d7c66a0 | |||
| 3adc301935 | |||
| 9232c673e8 | |||
| c2cb411469 | |||
| 44ddc732a1 | |||
| d6ef3e0487 | |||
| 8c191bdb90 | |||
| 8246699915 | |||
| de9d47c289 | |||
| 39b1808cab | |||
| a78f9e7b9d | |||
| f573026853 | |||
| f98c98ecdd | |||
| 3f6314aab7 | |||
| 3051c155e2 | |||
| e686be5acd | |||
| d49f9b213a | |||
| 8f346d7832 | |||
| 163c6a4e0c | |||
| b9036001aa | |||
| b16b36588f | |||
| efaaeeaad1 | |||
| 5d93f7166e | |||
| 72ac956758 | |||
| 5cb7df174b | |||
| d15dae23c1 | |||
| c98a65bb6f | |||
| e701c79469 | |||
| 18cd3efe80 | |||
| d71974d385 | |||
| 0defdf0892 | |||
| 8d1f79b8a8 | |||
| 9dc426ea0f | |||
| 19a63b9d19 | |||
| ae97f956b3 | |||
| d619751144 | |||
| e431a1751f | |||
| 209f0aa019 | |||
| 70015a942c | |||
| 91cfcb28e7 | |||
| b2a09c1b8c | |||
| 59aaf47cbe | |||
| c426e753cd | |||
| c8cf97421b | |||
| 9718137ad3 | |||
| af1fb3fee7 | |||
| 025baf257a | |||
| 8239ab6e1b | |||
| 1f018f954e | |||
| fd78ddf641 | |||
| 7662f1f050 | |||
| 890bea2571 | |||
| f57f6dc32d | |||
| 14863e3357 | |||
|  | 58f01c567c | ||
| 937368c753 | |||
| d8c11875d4 | |||
| bacd9e77f0 | |||
| 69d755ba32 | |||
| 31fb95e3b0 | |||
| 7d0f9870dd | |||
| 4a493b4e8d | |||
| 341dc819a0 | |||
| b58aecf7a5 | |||
| 301c017d5e | |||
| 1a4b676635 | |||
| ce54bef0b4 | |||
| 2699d29d7b | |||
| 63a07d58ca | |||
| 59fe332fe0 | |||
| 33723f4ea2 | |||
| c0ee55069e | |||
| 492ae4a225 | |||
| dcdb324391 | |||
| 90685cfdbf | |||
| ab61894373 | |||
| 662e0ade64 | |||
| 75aa847ae1 | |||
| c013228f79 | |||
| 740daf95ae | |||
| 768d29f93e | |||
| 837e084a5a | |||
| caea1b9572 | |||
| 0a255f161a | |||
| 85a2da4b5c | |||
| 647ef3049b | |||
| 7b48a5b6e2 | |||
| ec2e3da513 | |||
| 72729e410b | |||
| 5a9205a9b8 | |||
| a33601158f | |||
| 3c6b37b567 | |||
| 9b18ada78d | |||
| d57bb607e4 | |||
| 1f88ee4a0c | |||
| a32317e72f | |||
| b60cbe3854 | |||
| e0b150aa2a | |||
| 2bdfcb994e | |||
| d5c6014548 | |||
| de6fcacfd0 | |||
|  | 993f62b6cf | ||
| aabd74d7d7 | |||
| 15b307a88f | |||
| 72b338bfc2 | |||
| 267486774c | |||
| b94a568ef1 | |||
| b773ccfc8f | |||
| fd5c28e073 | |||
| 4c232829b6 | |||
| ddf1036009 | |||
| 9b3e5c23a0 | |||
| a7eae9d46b | |||
| 8c3e9d6273 | |||
| f306cc6c16 | |||
| 643cdb29e3 | |||
| 89287a0100 | |||
| f9b02f65e0 | |||
| 41169e2848 | |||
| ba36bc709c | |||
| 4005416233 | |||
| db4a6315cd | |||
| af38fdea64 | |||
| 172df69340 | |||
| a030a0ef16 | |||
| 7a6cc2739f | |||
| 41c9701e18 | |||
| 16e79ed608 | |||
| f401e1879b | |||
| 72b451d322 | |||
| 5350c46e0a | |||
| 1f5c5774e1 | |||
| 3b29502e7e | |||
| abc7e9fd05 | |||
| dd5ce77102 | |||
| dabaa3d1e1 | |||
| a6604a3a6d | |||
| 09a3e0e294 | |||
| f20ca53a2a | |||
| a2b912500c | |||
| 7de3d196ba | |||
| 6d5669aaf8 | |||
| 2c583509a2 | |||
| 3480637600 | |||
| f4665f51b1 | |||
| 810212dc12 | |||
| c3210df517 | |||
| 9f5c354433 | |||
| 23d9fef2b1 | |||
| df3087de7d | |||
| 5dd8318dab | |||
| 56c8bcce20 | |||
| 1c4961db5b | |||
| 5e0d01ea5b | |||
| e8938621fc | |||
| 8c8dcdd8e1 | |||
| 5085c9af90 | |||
| 85bc743c8e | |||
| b8efa644e3 | |||
| c18628a4ca | |||
| 535e24c9c2 | |||
| 04308b1003 | |||
| 43c626141e | |||
| c49266e4c1 | |||
| 6677b9232f | |||
| 76e792be88 | |||
| 5eac3d9d40 | |||
| 64593f09b7 | |||
| e20b68799f | |||
| 378878967a | |||
| 251ebe7056 | |||
| 615e4d5467 | |||
| a4f602d651 | |||
| c48512fc45 | |||
| d75822c465 | |||
| 4feeba5150 | |||
| e1237363f0 | |||
| b1550b31c5 | |||
| 81b9fd9f12 | |||
| d3559ede21 | |||
| ef6ccca3f9 | |||
| f781e9648f | |||
| 18d2eea029 | |||
| a95bdab8bf | |||
| eaeb1ed0ea | |||
| f9d6377fe4 | |||
| 30cf72de78 | |||
| fd49dec34c | |||
| cdd1cdd526 | |||
| bce363e8ff | |||
| 80f609b8a2 | |||
| 6205e9a353 | |||
| 12f7e1f115 | |||
| 296ad969f4 | |||
| d25c08447e | |||
| 7502a75753 | |||
| 1a14db1a17 | |||
| 67d8bcac21 | |||
| 4ca27317b4 | |||
| dc214e878f | |||
| d669dba320 | |||
| 235f4a58e9 | |||
| 03c1d08d8c | |||
| cc36a8b51d | |||
| d743ad83e3 | |||
| 194c258dcd | |||
| e0e1ae1108 | |||
| ee73443374 | |||
| 88801f9186 | |||
| 524d469a0d | |||
| c7b225ff00 | |||
| ba84f6d9c0 | |||
| 6a72f9f43f | |||
| efc0b2d858 | |||
| f140807886 | |||
| 37a13f1418 | |||
| 1cc0660a93 | |||
| 14da2ae388 | |||
| 9ee4d43c89 | |||
| fcac551806 | |||
| 044d8fa46d | |||
| 33f5404820 | |||
| 04a30e67d3 | |||
| 08183ed952 | |||
| 4fac231c43 | |||
| 30e356e3e0 | |||
| 36712557cb | |||
| c6aeca7e2b | |||
| 92c18f8bf7 | |||
| e86f40c620 | |||
| 072235f032 | |||
| 9b76a6b599 | |||
| d94dbd6c03 | |||
| b2db5bde2b | |||
| f8c5cf74f8 | |||
| 231076496a | |||
| a1b3baa5c9 | |||
| 8378f7ae0b | |||
| d4b75bcb71 | |||
| b0c7de2e92 | |||
| 844e218197 | |||
| a7c8e07eb7 | |||
| 5d99ec7673 | |||
| 2f92820895 | |||
| 527113a099 | |||
| 381b4ce0c2 | |||
| 6d8f5d5d65 | |||
| b74fb2b1d7 | |||
| d67b413860 | |||
| ec1f5afb84 | |||
| 1ce4267945 | |||
|  | 2da00ca814 | ||
|  | f7c0dff73c | ||
|  | 422bb77f61 | ||
|  | d51d2491ca | ||
| db39c5a576 | |||
| c6c5971325 | |||
| 5181612f62 | |||
|  | 5f33fae3d7 | ||
| 24fcac9318 | |||
| 514f2ef928 | |||
| 7d252d3cc8 | |||
| a1581379fd | |||
| a5f90ab105 | |||
| ddd7e2d50b | |||
| 3bacc356af | |||
| 797ca3a387 | |||
| ed751f5cdd | |||
| 01a580cee5 | |||
| 6fd14d3c49 | |||
| a1b524ab9d | |||
| 9bd0e237ea | |||
| 97d4f2cbe9 | |||
| 9307fbcbf4 | |||
| 679150326f | |||
| 773a2eaed0 | |||
| 203d343880 | |||
| 26ed50a7a1 | |||
| 050705c370 | |||
| d3c5979d3e | |||
| 8102a0f40b | |||
| 87fabdc8f9 | |||
|  | 7889476bc9 | ||
| abfaf06f1a | |||
| 8bd9e039da | |||
|  | 5cfccb97b1 | ||
|  | 54428112f8 | ||
| 18c12e60fe | |||
| 1000eb6d2c | |||
| 27114615a5 | |||
| 43c1f7be09 | |||
|  | 09bbbf0b3d | ||
|  | 2db886ea13 | ||
|  | e88d875bd9 | ||
| 57c3ee0360 | |||
| e1600751e0 | |||
| be47dcdba2 | |||
| fd30ae04bf | |||
| 19628736c1 | |||
| 4ced3d39df | |||
| be59f7a2c6 | |||
| 1665cf1eb9 | |||
| 47df3adce5 | |||
| f64fc0e54a | |||
| 314957218e | |||
| babb111fa6 | |||
|  | b051809869 | ||
|  | 32ec7a2339 | ||
| 3bce7ea344 | |||
| 76ed63395c | |||
| 19f324a1cf | |||
| 4b41d3b039 | |||
| 2ce41be8cc | |||
| c9f2187cc2 | |||
| a47fb5fed7 | |||
| 318a2a24fd | |||
| 2224a8ccbd | |||
| 48e2bec9ce | |||
| 6a1807efc8 | |||
| 0ad6e63733 | |||
| 6255e246e7 | |||
| 808fae0480 | |||
|  | 44d2402f4b | ||
|  | 7da14dbb6c | ||
| cc597b3cfb | |||
| 60af058ba4 | |||
|  | 608e784205 | ||
|  | 36041dd41b | ||
| 17aee8f220 | |||
| 294198958d | |||
|  | fe824f90ef | ||
|  | a560ebdb70 | ||
| 63faa9397e | |||
| 4df6e51e82 | |||
| cef4119afa | |||
| bee765714e | |||
| edff79abb6 | |||
|  | 2505fc1bf7 | ||
| d400434e89 | |||
| 4bd438d692 | |||
| 828140ed2b | |||
| 9a2cae0c70 | |||
| 3a621b8323 | |||
| 0360fb413c | |||
| 5b86a0f6d9 | |||
| 24c14fb7ca | |||
| fbbcd51df5 | |||
| 5a9578d554 | |||
|  | 5cb1069c1c | ||
|  | 0c8cad6608 | ||
|  | b865f78e22 | ||
|  | bc7b066864 | ||
|  | 7b4af08296 | ||
| c77bc476aa | |||
| b802bb01e6 | |||
| 61f9add741 | |||
| d8e9eef8b1 | |||
| 7bddeca783 | |||
|  | d03565ba26 | ||
|  | 36fe81cb3e | ||
|  | f9edab8f36 | ||
|  | ffe95a12f2 | ||
|  | bcef200765 | ||
|  | dc0e3989d4 | ||
|  | b9f821652c | ||
|  | b04c6aa345 | ||
| b05e354459 | |||
| ce8cfd6a68 | |||
|  | 234d4d0fa9 | ||
|  | 4d05d9a539 | ||
|  | 3f16310f67 | ||
| 762351f76e | |||
|  | 2f33b7fd86 | ||
| 8efbd676ce | |||
| 2fc7c8ab1e | |||
| dc5a90cf1a | |||
|  | 2e49bc4709 | ||
|  | 4e7046bd28 | ||
|  | 3eab510f5a | ||
|  | 8c3b745d4d | ||
| db9475cf3b | |||
|  | 31c212807b | ||
|  | aca8caa5c3 | ||
|  | b30ef2ef2b | ||
| 62637badcb | |||
|  | ddcd9899b3 | ||
|  | d3db06a90c | ||
|  | 92e211a21a | ||
|  | 1098ba4c7d | ||
| 2c5a843835 | |||
| 204e289627 | |||
| fd731b2ecf | |||
| e733e413ef | |||
|  | e1abd8e85c | ||
|  | 3b1abc9ae8 | ||
|  | 6b8737e182 | ||
|  | baab800a1c | ||
|  | e2bde3bd01 | ||
|  | f849780aac | ||
|  | 37004a1f6e | ||
|  | d483be05a6 | ||
| 0c89178542 | |||
| c8999f8250 | |||
| 2fd1f26325 | |||
|  | 03774a540f | ||
| f559c1e215 | |||
|  | ea130df02b | ||
|  | 2ac780bdaa | ||
|  | a9f474fa62 | ||
|  | 3a476e0db4 | ||
|  | b9221fa949 | ||
|  | 07db6e21db | ||
|  | e5e998df36 | ||
| 112ed5b140 | |||
| a781510a41 | |||
| bbbcffcfcb | |||
|  | 13bdfff9f8 | ||
|  | ef7c39e4e9 | ||
|  | ee085cbbb1 | ||
| 35a94b4a75 | |||
|  | da68d87a5f | ||
|  | af28d5c65b | ||
|  | b5ca868050 | ||
| 4a5dd47bc0 | |||
|  | 71a5f72381 | ||
|  | c1ba1ceb7c | ||
|  | 035ce9f1b9 | ||
|  | eb2534ff94 | ||
|  | d93d73dc3a | ||
|  | 6bfd0621ad | ||
|  | b88f5bf2e4 | ||
| 43ff5d416a | |||
| 90fc81776f | |||
| 0e8316b9f5 | |||
| 01f1f94dd6 | |||
| bfd5a58461 | |||
| 240831d6e5 | |||
| 394bff34e5 | |||
| 000918844a | |||
| f44a1597c0 | |||
| 1cfc6a9ae3 | |||
| b4a5fdebab | |||
| 4970018afb | |||
| 8998cc3ac4 | |||
| bee4dc403b | |||
| edbe916247 | |||
| 73334a7dd7 | |||
| 497068627c | |||
| 89361e17e6 | |||
| 18ec4bf9f1 | |||
| 2e75f784dd | |||
| c7179bd0a0 | |||
| b38c099414 | |||
| e7f5d19707 | |||
| 4ae2e70586 | |||
| c93072d9b4 | |||
| 721e728275 | |||
| bfd96d9ccc | |||
| 3f0e0bb9a9 | |||
| 2276605e6d | |||
| a6883a624a | |||
| fc3cf92dcf | |||
| e69f9dc2d8 | |||
| 473d79a32d | |||
| 2f8f0227ba | |||
| 7bf0053974 | |||
| 5f7e7e31bf | |||
| a1bc5377db | |||
| f4b93253a8 | |||
|  | 56733c854c | ||
| 9e170380db | |||
| 23f0beb646 | |||
| a0af0ad300 | |||
|  | 9187021cda | ||
| 4fb8fe7d08 | |||
|  | c882786726 | ||
| 7f6a05c101 | |||
| 06f1aad38e | |||
| 2aa9b4b2d1 | |||
| 152ede26e3 | |||
| 3f43c8d946 | |||
| 85b1cb8759 | |||
| 82069f3bef | |||
| 3a31135807 | |||
|  | 6482d43af0 | ||
|  | e221ef070f | ||
|  | 6b547c4ddd | ||
|  | 63ef099dc3 | ||
| f4cf600d22 | |||
|  | f9111ffe5e | ||
|  | cd3329baae | ||
|  | feafd48443 | ||
|  | eb152bc6c7 | ||
| 4376f9dc26 | |||
|  | 7f7487836c | ||
|  | 7046b23a27 | ||
| 6ebceb4ce7 | |||
|  | 3d9845e1b3 | ||
|  | 07118a870f | ||
| abb718603e | |||
|  | 9f170c1186 | ||
|  | 94d4f13a28 | ||
| 4c6bf597a9 | |||
|  | 4c091745dd | ||
|  | 406f6f5cdd | ||
|  | 4250eca710 | ||
| 3bd414506a | |||
|  | a9dbd503e3 | ||
| ec0904ffb1 | |||
|  | b80b05fbd8 | ||
| d9a4247b8e | |||
|  | 9d5164bd13 | ||
| ec6d36b44c | |||
| 7e7a571f5a | |||
|  | 9a61ea59b2 | ||
|  | 5dc141a14a | ||
|  | a0f8ec156b | ||
|  | 7383c85b58 | ||
|  | aed0faebf0 | ||
| f0b9f8043b | |||
|  | 58dfe98448 | ||
|  | f14ba0e97f | ||
|  | 981b5cebca | ||
| 4e3a93f126 | |||
|  | c391a07d70 | ||
|  | 7faa25e103 | ||
|  | 12c3a6ef6f | ||
| 4c1bd21f3d | |||
| abfc6c4c47 | |||
| afb2ef21f5 | |||
| 06bb8feeb5 | |||
| a112586c2d | |||
|  | 8d40008e5d | ||
|  | a9afd7e0a9 | ||
| 28a0426096 | |||
|  | dee04269bd | ||
|  | 6c7ceb3eb3 | ||
|  | 4dda9eb24c | ||
| 92258f4925 | |||
| 5b1b1cdaaa | |||
| 875989e3a9 | |||
| 74c17f433a | |||
|  | 2903207670 | ||
|  | c0723665af | ||
| 83a648eb90 | |||
| 5204599a08 | |||
| fcdce8706f | |||
| 5192212e0e | |||
| 376d695416 | |||
| e25425ffe9 | |||
| 78d40f1abc | |||
| 78d99da6df | |||
| f797c98d45 | |||
| 491ca28ab2 | |||
| 7f71c89ffb | |||
| 411d5720b9 | |||
| 872dd3fd71 | |||
| 521e9da4e3 | |||
| ed8371e08a | |||
| 160590658b | |||
| 002ac7902d | |||
| e527b198f9 | |||
| d68561b372 | |||
| c292289f29 | |||
| e053517765 | |||
| 66d045c2a7 | |||
| e1410ed402 | |||
| 1031794d85 | |||
| 5d2b45b3e5 | |||
| 73b09fe9cb | |||
| cd2ecb22b1 | |||
| ad66131e01 | |||
| f401c418c5 | |||
| 7b8db90f75 | |||
| 0431ba12c5 | |||
| 3731bb7532 | |||
| a1a3fa45b1 | |||
| 59541ec0e8 | |||
| b334cc377f | |||
| b1467838da | |||
| 20901fb26c | |||
| 295f948104 | |||
| 977ab8f6c9 | |||
| c3e2d23a63 | 
							
								
								
									
										17
									
								
								.gitea/workflows/tests.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.gitea/workflows/tests.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | name: Tests | ||||||
|  | on: | ||||||
|  |   pull_request: | ||||||
|  |  | ||||||
|  | env: | ||||||
|  |   NIXPKGS_ALLOW_UNFREE: 1 | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   install: | ||||||
|  |     name: Tests | ||||||
|  |     runs-on: nixos-x86_64-linux | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           submodules: recursive | ||||||
|  |       - name: codegen causes no changes | ||||||
|  |         run: ./bin/assert-no-changes-wrapper.sh | ||||||
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | node_modules | ||||||
|  | dist | ||||||
|  | .direnv | ||||||
|  | /after.txt | ||||||
|  | /before.txt | ||||||
|  | **/__pycache__/** | ||||||
							
								
								
									
										6
									
								
								bin/assert-no-changes-wrapper.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								bin/assert-no-changes-wrapper.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | GQL_DIR=$(dirname $(dirname "$(realpath "$BASH_SOURCE")")) | ||||||
|  |  | ||||||
|  | cd $GQL_DIR | ||||||
|  |  | ||||||
|  | LD_LIBRARY_PATH="" nix develop --impure --command bash "$GQL_DIR/bin/assert-no-changes.sh" | ||||||
							
								
								
									
										17
									
								
								bin/assert-no-changes.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								bin/assert-no-changes.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | git ls-files | xargs md5sum > before.txt | ||||||
|  |  | ||||||
|  | yarn install | ||||||
|  | yarn graphql-codegen | ||||||
|  | prettier ./src --write | ||||||
|  | for proto in $(find ./rbproto -iname '*.proto'); do | ||||||
|  | 		name=$(basename "$proto" .proto) | ||||||
|  | 		protoc -I=./rbproto --python_out=./rbproto/python --pyi_out=./rbproto/python ./rbproto/shot.proto | ||||||
|  |     yarn pbjs ./rbproto/shot.proto --ts ./rbproto/ts/shot.ts | ||||||
|  | done | ||||||
|  | prettier ./rbproto --write | ||||||
|  |  | ||||||
|  | git ls-files | xargs md5sum > after.txt | ||||||
|  |  | ||||||
|  |  | ||||||
|  | diff before.txt after.txt | ||||||
| @@ -1,5 +1,7 @@ | |||||||
| overwrite: true | overwrite: true | ||||||
| schema: "src/schema.gql" | schema: | ||||||
|  |   - "src/schema.gql" | ||||||
|  |   - "src/client-schema.gql" | ||||||
| documents: "src/**/*.gql" | documents: "src/**/*.gql" | ||||||
| generates: | generates: | ||||||
|   src/index.tsx: |   src/index.tsx: | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								flake.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								flake.lock
									
									
									
										generated
									
									
									
								
							| @@ -20,9 +20,7 @@ | |||||||
|     }, |     }, | ||||||
|     "gitignore": { |     "gitignore": { | ||||||
|       "inputs": { |       "inputs": { | ||||||
|         "nixpkgs": [ |         "nixpkgs": ["nixpkgs"] | ||||||
|           "nixpkgs" |  | ||||||
|         ] |  | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1703887061, |         "lastModified": 1703887061, | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ | |||||||
|     in |     in | ||||||
|       with pkgs; { |       with pkgs; { | ||||||
|         devShell = mkShell { |         devShell = mkShell { | ||||||
|           buildInputs = [nodejs yarn watchman alejandra nodePackages.prettier]; |           buildInputs = [nodejs yarn watchman alejandra nodePackages.prettier just protobuf]; | ||||||
|         }; |         }; | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								justfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								justfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | NIX := "LD_LIBRARY_PATH='' nix" | ||||||
|  | PROTOBUF_DIR := "$PWD/rbproto" | ||||||
|  |  | ||||||
|  | prettier-gql: | ||||||
|  | 	#!/usr/bin/env bash | ||||||
|  | 	set -euxo pipefail | ||||||
|  | 	{{NIX}} develop --impure --command prettier ./src --write | ||||||
|  |  | ||||||
|  | gql-codegen: | ||||||
|  | 	#!/usr/bin/env bash | ||||||
|  | 	set -euxo pipefail | ||||||
|  | 	{{NIX}} develop --impure --command bash -c 'yarn install && yarn graphql-codegen' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | gql: gql-codegen prettier-gql | ||||||
|  |  | ||||||
|  | protobuf-compile-a-python name: | ||||||
|  | 	protoc -I={{ PROTOBUF_DIR }} --python_out={{ PROTOBUF_DIR }}/python --pyi_out={{ PROTOBUF_DIR }}/python {{ PROTOBUF_DIR }}/shot.proto | ||||||
|  |  | ||||||
|  | protobuf-compile-a-js name: | ||||||
|  | 	#!/usr/bin/env bash | ||||||
|  | 	set -euxo pipefail | ||||||
|  | 	{{NIX}} develop --impure --command bash -c 'yarn pbjs {{ PROTOBUF_DIR }}/shot.proto --ts {{ PROTOBUF_DIR }}/ts/shot.ts && yarn prettier ./rbproto --write' | ||||||
|  |  | ||||||
|  | protobuf-compile-all-js: | ||||||
|  | 	#!/usr/bin/env bash | ||||||
|  | 	for proto in $(find {{ PROTOBUF_DIR }} -iname '*.proto'); do | ||||||
|  | 		name=$(basename "$proto" .proto) | ||||||
|  | 		just protobuf-compile-a-js $name | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | protobuf-compile-all-python: | ||||||
|  | 	#!/usr/bin/env bash | ||||||
|  | 	for proto in $(find {{ PROTOBUF_DIR }} -iname '*.proto'); do | ||||||
|  | 		name=$(basename "$proto" .proto) | ||||||
|  | 		just protobuf-compile-a-python $name | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | protobuf-compile-everything: protobuf-compile-all-js protobuf-compile-all-python | ||||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @@ -17,7 +17,15 @@ | |||||||
|     "@graphql-codegen/typescript": "^4.0.1", |     "@graphql-codegen/typescript": "^4.0.1", | ||||||
|     "@graphql-codegen/typescript-operations": "^4.0.1", |     "@graphql-codegen/typescript-operations": "^4.0.1", | ||||||
|     "@graphql-codegen/typescript-react-apollo": "^4.2.0", |     "@graphql-codegen/typescript-react-apollo": "^4.2.0", | ||||||
|     "graphql": "^16.8.1" |     "graphql": "^16.8.1", | ||||||
|  |     "pbjs": "^0.0.14", | ||||||
|  |     "prettier": "^3.2.5", | ||||||
|  |     "prettier-plugin-organize-imports": "^3.2.4" | ||||||
|  |   }, | ||||||
|  |   "prettier": { | ||||||
|  |     "plugins": [ | ||||||
|  |       "prettier-plugin-organize-imports" | ||||||
|  |     ] | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "typescript": "^4.x" |     "typescript": "^4.x" | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | [tool.poetry] | ||||||
|  | name = "rbproto" | ||||||
|  | version = "0.1.0" | ||||||
|  | description = "" | ||||||
|  | authors = ["Mike Kalange <countablecloud@gmail.com>"] | ||||||
|  | readme = "README.md" | ||||||
|  | packages = [{include = "rbproto"}] | ||||||
|  |  | ||||||
|  | [tool.poetry.dependencies] | ||||||
|  | python = ">=3.10,<=3.13" | ||||||
|  | protobuf = "^4.25.3" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | [build-system] | ||||||
|  | requires = ["poetry-core"] | ||||||
|  | build-backend = "poetry.core.masonry.api" | ||||||
							
								
								
									
										1
									
								
								rbproto/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								rbproto/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | from .python.shot_pb2 import *  # noqa: F401 | ||||||
							
								
								
									
										49
									
								
								rbproto/python/shot_pb2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								rbproto/python/shot_pb2.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | # Generated by the protocol buffer compiler.  DO NOT EDIT! | ||||||
|  | # source: shot.proto | ||||||
|  | """Generated protocol buffer code.""" | ||||||
|  | from google.protobuf import descriptor as _descriptor | ||||||
|  | from google.protobuf import descriptor_pool as _descriptor_pool | ||||||
|  | from google.protobuf import symbol_database as _symbol_database | ||||||
|  | from google.protobuf.internal import builder as _builder | ||||||
|  | # @@protoc_insertion_point(imports) | ||||||
|  |  | ||||||
|  | _sym_db = _symbol_database.Default() | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nshot.proto\x12\x0fserialized_shot\"?\n\x03\x42ox\x12\x0c\n\x04left\x18\x01 \x01(\x02\x12\x0b\n\x03top\x18\x02 \x01(\x02\x12\r\n\x05width\x18\x03 \x01(\x02\x12\x0e\n\x06height\x18\x04 \x01(\x02\"\x1d\n\x05Point\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\"\x7f\n\rBallDetection\x12.\n\x0eplane_position\x18\x01 \x01(\x0b\x32\x16.serialized_shot.Point\x12(\n\nannotation\x18\x02 \x01(\x0b\x32\x14.serialized_shot.Box\x12\x14\n\x0cinterpolated\x18\x03 \x01(\x08\"T\n\x10RLEBallDetection\x12\x31\n\tdetection\x18\x01 \x01(\x0b\x32\x1e.serialized_shot.BallDetection\x12\r\n\x05\x63ount\x18\x02 \x01(\r\"L\n\x13RLEDetectionHistory\x12\x35\n\ndetections\x18\x01 \x03(\x0b\x32!.serialized_shot.RLEBallDetection\"F\n\x10\x44\x65tectionHistory\x12\x32\n\ndetections\x18\x01 \x03(\x0b\x32\x1e.serialized_shot.BallDetection\"\xfc\x01\n\rCollisionInfo\x12\x0e\n\x06source\x18\x01 \x01(\r\x12M\n\x10\x62\x61ll_identifiers\x18\x02 \x03(\x0b\x32\x33.serialized_shot.CollisionInfo.BallIdentifiersEntry\x12\x17\n\x0fwall_identifier\x18\x03 \x01(\r\x12\x13\n\x0b\x66rame_index\x18\x04 \x01(\r\x12\x0e\n\x06static\x18\x05 \x01(\x08\x1aN\n\x14\x42\x61llIdentifiersEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.serialized_shot.Point:\x02\x38\x01\"\xcc\x02\n\x04Path\x12\x13\n\x0bstart_frame\x18\x01 \x01(\r\x12\x11\n\tend_frame\x18\x02 \x01(\r\x12\x37\n\ndetections\x18\x03 \x01(\x0b\x32!.serialized_shot.DetectionHistoryH\x00\x12>\n\x0erle_detections\x18\x04 \x01(\x0b\x32$.serialized_shot.RLEDetectionHistoryH\x00\x12\x15\n\x0bnot_present\x18\x05 \x01(\x08H\x00\x12\x11\n\tis_static\x18\x06 \x01(\x08\x12\x32\n\nstart_info\x18\x07 \x01(\x0b\x32\x1e.serialized_shot.CollisionInfo\x12\x30\n\x08\x65nd_info\x18\x08 \x01(\x0b\x32\x1e.serialized_shot.CollisionInfoB\x13\n\x11\x64\x65tection_history\"R\n\x11IdentifierHistory\x12\x17\n\x0f\x62\x61ll_identifier\x18\x01 \x01(\r\x12$\n\x05paths\x18\x02 \x03(\x0b\x32\x15.serialized_shot.Path\"\xf4\x01\n\x12KeyBallIdentifiers\x12\x10\n\x08\x63ue_ball\x18\x01 \x01(\r\x12\x13\n\x0bobject_ball\x18\x02 \x01(\r\x12\x13\n\x0btarget_ball\x18\x03 \x01(\r\x12\x18\n\x10\x63ontact_sequence\x18\x04 \x03(\r\x12\x18\n\x0b\x63ue_ball_id\x18\x05 \x01(\rH\x00\x88\x01\x01\x12\x1b\n\x0eobject_ball_id\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0etarget_ball_id\x18\x07 \x01(\rH\x02\x88\x01\x01\x42\x0e\n\x0c_cue_ball_idB\x11\n\x0f_object_ball_idB\x11\n\x0f_target_ball_id\"\xa8\x01\n\x04Shot\x12@\n\x14identifier_histories\x18\x03 \x03(\x0b\x32\".serialized_shot.IdentifierHistory\x12\x36\n\tkey_balls\x18\x04 \x01(\x0b\x32#.serialized_shot.KeyBallIdentifiers\x12\x13\n\x0bstart_index\x18\x05 \x01(\r\x12\x11\n\tend_index\x18\x06 \x01(\rb\x06proto3') | ||||||
|  |  | ||||||
|  | _globals = globals() | ||||||
|  | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) | ||||||
|  | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'shot_pb2', _globals) | ||||||
|  | if _descriptor._USE_C_DESCRIPTORS == False: | ||||||
|  |   DESCRIPTOR._options = None | ||||||
|  |   _globals['_COLLISIONINFO_BALLIDENTIFIERSENTRY']._options = None | ||||||
|  |   _globals['_COLLISIONINFO_BALLIDENTIFIERSENTRY']._serialized_options = b'8\001' | ||||||
|  |   _globals['_BOX']._serialized_start=31 | ||||||
|  |   _globals['_BOX']._serialized_end=94 | ||||||
|  |   _globals['_POINT']._serialized_start=96 | ||||||
|  |   _globals['_POINT']._serialized_end=125 | ||||||
|  |   _globals['_BALLDETECTION']._serialized_start=127 | ||||||
|  |   _globals['_BALLDETECTION']._serialized_end=254 | ||||||
|  |   _globals['_RLEBALLDETECTION']._serialized_start=256 | ||||||
|  |   _globals['_RLEBALLDETECTION']._serialized_end=340 | ||||||
|  |   _globals['_RLEDETECTIONHISTORY']._serialized_start=342 | ||||||
|  |   _globals['_RLEDETECTIONHISTORY']._serialized_end=418 | ||||||
|  |   _globals['_DETECTIONHISTORY']._serialized_start=420 | ||||||
|  |   _globals['_DETECTIONHISTORY']._serialized_end=490 | ||||||
|  |   _globals['_COLLISIONINFO']._serialized_start=493 | ||||||
|  |   _globals['_COLLISIONINFO']._serialized_end=745 | ||||||
|  |   _globals['_COLLISIONINFO_BALLIDENTIFIERSENTRY']._serialized_start=667 | ||||||
|  |   _globals['_COLLISIONINFO_BALLIDENTIFIERSENTRY']._serialized_end=745 | ||||||
|  |   _globals['_PATH']._serialized_start=748 | ||||||
|  |   _globals['_PATH']._serialized_end=1080 | ||||||
|  |   _globals['_IDENTIFIERHISTORY']._serialized_start=1082 | ||||||
|  |   _globals['_IDENTIFIERHISTORY']._serialized_end=1164 | ||||||
|  |   _globals['_KEYBALLIDENTIFIERS']._serialized_start=1167 | ||||||
|  |   _globals['_KEYBALLIDENTIFIERS']._serialized_end=1411 | ||||||
|  |   _globals['_SHOT']._serialized_start=1414 | ||||||
|  |   _globals['_SHOT']._serialized_end=1582 | ||||||
|  | # @@protoc_insertion_point(module_scope) | ||||||
							
								
								
									
										135
									
								
								rbproto/python/shot_pb2.pyi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								rbproto/python/shot_pb2.pyi
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | |||||||
|  | from google.protobuf.internal import containers as _containers | ||||||
|  | from google.protobuf import descriptor as _descriptor | ||||||
|  | from google.protobuf import message as _message | ||||||
|  | from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union | ||||||
|  |  | ||||||
|  | DESCRIPTOR: _descriptor.FileDescriptor | ||||||
|  |  | ||||||
|  | class Box(_message.Message): | ||||||
|  |     __slots__ = ["left", "top", "width", "height"] | ||||||
|  |     LEFT_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     TOP_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     WIDTH_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     HEIGHT_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     left: float | ||||||
|  |     top: float | ||||||
|  |     width: float | ||||||
|  |     height: float | ||||||
|  |     def __init__(self, left: _Optional[float] = ..., top: _Optional[float] = ..., width: _Optional[float] = ..., height: _Optional[float] = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class Point(_message.Message): | ||||||
|  |     __slots__ = ["x", "y"] | ||||||
|  |     X_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     Y_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     x: float | ||||||
|  |     y: float | ||||||
|  |     def __init__(self, x: _Optional[float] = ..., y: _Optional[float] = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class BallDetection(_message.Message): | ||||||
|  |     __slots__ = ["plane_position", "annotation", "interpolated"] | ||||||
|  |     PLANE_POSITION_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     ANNOTATION_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     INTERPOLATED_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     plane_position: Point | ||||||
|  |     annotation: Box | ||||||
|  |     interpolated: bool | ||||||
|  |     def __init__(self, plane_position: _Optional[_Union[Point, _Mapping]] = ..., annotation: _Optional[_Union[Box, _Mapping]] = ..., interpolated: bool = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class RLEBallDetection(_message.Message): | ||||||
|  |     __slots__ = ["detection", "count"] | ||||||
|  |     DETECTION_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     COUNT_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     detection: BallDetection | ||||||
|  |     count: int | ||||||
|  |     def __init__(self, detection: _Optional[_Union[BallDetection, _Mapping]] = ..., count: _Optional[int] = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class RLEDetectionHistory(_message.Message): | ||||||
|  |     __slots__ = ["detections"] | ||||||
|  |     DETECTIONS_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     detections: _containers.RepeatedCompositeFieldContainer[RLEBallDetection] | ||||||
|  |     def __init__(self, detections: _Optional[_Iterable[_Union[RLEBallDetection, _Mapping]]] = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class DetectionHistory(_message.Message): | ||||||
|  |     __slots__ = ["detections"] | ||||||
|  |     DETECTIONS_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     detections: _containers.RepeatedCompositeFieldContainer[BallDetection] | ||||||
|  |     def __init__(self, detections: _Optional[_Iterable[_Union[BallDetection, _Mapping]]] = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class CollisionInfo(_message.Message): | ||||||
|  |     __slots__ = ["source", "ball_identifiers", "wall_identifier", "frame_index", "static"] | ||||||
|  |     class BallIdentifiersEntry(_message.Message): | ||||||
|  |         __slots__ = ["key", "value"] | ||||||
|  |         KEY_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |         VALUE_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |         key: int | ||||||
|  |         value: Point | ||||||
|  |         def __init__(self, key: _Optional[int] = ..., value: _Optional[_Union[Point, _Mapping]] = ...) -> None: ... | ||||||
|  |     SOURCE_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     BALL_IDENTIFIERS_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     WALL_IDENTIFIER_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     FRAME_INDEX_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     STATIC_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     source: int | ||||||
|  |     ball_identifiers: _containers.MessageMap[int, Point] | ||||||
|  |     wall_identifier: int | ||||||
|  |     frame_index: int | ||||||
|  |     static: bool | ||||||
|  |     def __init__(self, source: _Optional[int] = ..., ball_identifiers: _Optional[_Mapping[int, Point]] = ..., wall_identifier: _Optional[int] = ..., frame_index: _Optional[int] = ..., static: bool = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class Path(_message.Message): | ||||||
|  |     __slots__ = ["start_frame", "end_frame", "detections", "rle_detections", "not_present", "is_static", "start_info", "end_info"] | ||||||
|  |     START_FRAME_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     END_FRAME_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     DETECTIONS_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     RLE_DETECTIONS_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     NOT_PRESENT_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     IS_STATIC_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     START_INFO_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     END_INFO_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     start_frame: int | ||||||
|  |     end_frame: int | ||||||
|  |     detections: DetectionHistory | ||||||
|  |     rle_detections: RLEDetectionHistory | ||||||
|  |     not_present: bool | ||||||
|  |     is_static: bool | ||||||
|  |     start_info: CollisionInfo | ||||||
|  |     end_info: CollisionInfo | ||||||
|  |     def __init__(self, start_frame: _Optional[int] = ..., end_frame: _Optional[int] = ..., detections: _Optional[_Union[DetectionHistory, _Mapping]] = ..., rle_detections: _Optional[_Union[RLEDetectionHistory, _Mapping]] = ..., not_present: bool = ..., is_static: bool = ..., start_info: _Optional[_Union[CollisionInfo, _Mapping]] = ..., end_info: _Optional[_Union[CollisionInfo, _Mapping]] = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class IdentifierHistory(_message.Message): | ||||||
|  |     __slots__ = ["ball_identifier", "paths"] | ||||||
|  |     BALL_IDENTIFIER_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     PATHS_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     ball_identifier: int | ||||||
|  |     paths: _containers.RepeatedCompositeFieldContainer[Path] | ||||||
|  |     def __init__(self, ball_identifier: _Optional[int] = ..., paths: _Optional[_Iterable[_Union[Path, _Mapping]]] = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class KeyBallIdentifiers(_message.Message): | ||||||
|  |     __slots__ = ["cue_ball", "object_ball", "target_ball", "contact_sequence", "cue_ball_id", "object_ball_id", "target_ball_id"] | ||||||
|  |     CUE_BALL_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     OBJECT_BALL_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     TARGET_BALL_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     CONTACT_SEQUENCE_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     CUE_BALL_ID_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     OBJECT_BALL_ID_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     TARGET_BALL_ID_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     cue_ball: int | ||||||
|  |     object_ball: int | ||||||
|  |     target_ball: int | ||||||
|  |     contact_sequence: _containers.RepeatedScalarFieldContainer[int] | ||||||
|  |     cue_ball_id: int | ||||||
|  |     object_ball_id: int | ||||||
|  |     target_ball_id: int | ||||||
|  |     def __init__(self, cue_ball: _Optional[int] = ..., object_ball: _Optional[int] = ..., target_ball: _Optional[int] = ..., contact_sequence: _Optional[_Iterable[int]] = ..., cue_ball_id: _Optional[int] = ..., object_ball_id: _Optional[int] = ..., target_ball_id: _Optional[int] = ...) -> None: ... | ||||||
|  |  | ||||||
|  | class Shot(_message.Message): | ||||||
|  |     __slots__ = ["identifier_histories", "key_balls", "start_index", "end_index"] | ||||||
|  |     IDENTIFIER_HISTORIES_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     KEY_BALLS_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     START_INDEX_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     END_INDEX_FIELD_NUMBER: _ClassVar[int] | ||||||
|  |     identifier_histories: _containers.RepeatedCompositeFieldContainer[IdentifierHistory] | ||||||
|  |     key_balls: KeyBallIdentifiers | ||||||
|  |     start_index: int | ||||||
|  |     end_index: int | ||||||
|  |     def __init__(self, identifier_histories: _Optional[_Iterable[_Union[IdentifierHistory, _Mapping]]] = ..., key_balls: _Optional[_Union[KeyBallIdentifiers, _Mapping]] = ..., start_index: _Optional[int] = ..., end_index: _Optional[int] = ...) -> None: ... | ||||||
							
								
								
									
										77
									
								
								rbproto/shot.proto
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								rbproto/shot.proto
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | syntax = "proto3"; | ||||||
|  |  | ||||||
|  | package serialized_shot; | ||||||
|  |  | ||||||
|  | message Box { | ||||||
|  |   float left = 1; | ||||||
|  |   float top = 2; | ||||||
|  |   float width = 3; | ||||||
|  |   float height = 4; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | message Point { | ||||||
|  |   float x = 1; | ||||||
|  |   float y = 2; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | message BallDetection { | ||||||
|  |   Point plane_position = 1; | ||||||
|  |   Box annotation = 2; | ||||||
|  |   bool interpolated = 3; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | message RLEBallDetection { | ||||||
|  |   BallDetection detection = 1; | ||||||
|  |   uint32 count = 2; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | message RLEDetectionHistory { repeated RLEBallDetection detections = 1; } | ||||||
|  |  | ||||||
|  | message DetectionHistory { repeated BallDetection detections = 1; } | ||||||
|  |  | ||||||
|  | message CollisionInfo { | ||||||
|  |   uint32 source = 1; | ||||||
|  |   map<uint32, Point> ball_identifiers = 2; | ||||||
|  |   uint32 wall_identifier = 3; | ||||||
|  |   uint32 frame_index = 4; | ||||||
|  |   bool static = 5; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | message Path { | ||||||
|  |   uint32 start_frame = 1; | ||||||
|  |   uint32 end_frame = 2; | ||||||
|  |   oneof detection_history { | ||||||
|  |     DetectionHistory detections = 3; | ||||||
|  |     RLEDetectionHistory rle_detections = 4; | ||||||
|  |     bool not_present = 5; | ||||||
|  |   } | ||||||
|  |   bool is_static = 6; | ||||||
|  |   CollisionInfo start_info = 7; | ||||||
|  |   CollisionInfo end_info = 8; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | message IdentifierHistory { | ||||||
|  |   uint32 ball_identifier = 1; | ||||||
|  |   repeated Path paths = 2; | ||||||
|  | } | ||||||
|  | message KeyBallIdentifiers { | ||||||
|  |   uint32 cue_ball = 1; | ||||||
|  |   uint32 object_ball = 2; | ||||||
|  |   uint32 target_ball = 3; | ||||||
|  |  | ||||||
|  |   // For now this will just be cue->object/target->target | ||||||
|  |   // Long term this will potentially represent a linked list | ||||||
|  |   // of all balls in a shot. | ||||||
|  |   repeated uint32 contact_sequence = 4; | ||||||
|  |  | ||||||
|  |   optional uint32 cue_ball_id = 5; | ||||||
|  |   optional uint32 object_ball_id = 6; | ||||||
|  |   optional uint32 target_ball_id = 7; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | message Shot { | ||||||
|  |   repeated IdentifierHistory identifier_histories = 3; | ||||||
|  |   KeyBallIdentifiers key_balls = 4; | ||||||
|  |   uint32 start_index = 5; | ||||||
|  |   uint32 end_index = 6; | ||||||
|  | } | ||||||
							
								
								
									
										1628
									
								
								rbproto/ts/shot.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1628
									
								
								rbproto/ts/shot.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										25
									
								
								src/client-schema.gql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/client-schema.gql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | # see: https://www.apollographql.com/docs/react/local-state/managing-state-with-field-policies/ | ||||||
|  | directive @client on FIELD | ||||||
|  |  | ||||||
|  | extend type ShotGQL { | ||||||
|  |   startTime: Float! | ||||||
|  |   endTime: Float! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | extend type UploadStreamGQL { | ||||||
|  |   segmentEndFrames: [Int!]! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | extend type HLSPlaylistGQL { | ||||||
|  |   segmentStartTimes: [Float!]! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type SegmentEndFramesGQL { | ||||||
|  |   id: Int! | ||||||
|  |   segmentEndFrames: [Int!]! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type SegmentStartTimesGQL { | ||||||
|  |   id: Int! | ||||||
|  |   segmentStartTimes: [Float!]! | ||||||
|  | } | ||||||
							
								
								
									
										7200
									
								
								src/index.tsx
									
									
									
									
									
								
							
							
						
						
									
										7200
									
								
								src/index.tsx
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										12
									
								
								src/operations/aggregate.gql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/operations/aggregate.gql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | query GetAggregatedShotMetrics($aggregateInput: AggregateInputGQL!) { | ||||||
|  |   getAggregatedShotMetrics(aggregateInput: $aggregateInput) { | ||||||
|  |     aggregationIdentifiers { | ||||||
|  |       featureName | ||||||
|  |       groupName | ||||||
|  |     } | ||||||
|  |     targetMetrics { | ||||||
|  |       count | ||||||
|  |       makePercentage | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| query GetAggregateShots($bucketSets: [BucketSetInputGQL!]!) { |  | ||||||
|   getAggregateShots(bucketSets: $bucketSets) { |  | ||||||
|     featureBuckets { |  | ||||||
|       rangeKey |  | ||||||
|       lowerBound |  | ||||||
|     } |  | ||||||
|     targetMetrics { |  | ||||||
|       count |  | ||||||
|       makePercentage |  | ||||||
|       floatFeature { |  | ||||||
|         featureName |  | ||||||
|         average |  | ||||||
|         median |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
							
								
								
									
										9
									
								
								src/operations/config.gql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/operations/config.gql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | query getDeployedConfig { | ||||||
|  |   getDeployedConfig { | ||||||
|  |     allowNewUsers | ||||||
|  |     devMode | ||||||
|  |     environment | ||||||
|  |     firebase | ||||||
|  |     minimumAllowedAppVersion | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								src/operations/feed.gql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/operations/feed.gql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | query GetFeed( | ||||||
|  |   $limit: Int! = 5 | ||||||
|  |   $after: String = null | ||||||
|  |   $filters: VideoFilterInput = null | ||||||
|  | ) { | ||||||
|  |   getUserVideos(limit: $limit, after: $after, filters: $filters) { | ||||||
|  |     videos { | ||||||
|  |       id | ||||||
|  |       owner { | ||||||
|  |         username | ||||||
|  |       } | ||||||
|  |       name | ||||||
|  |       screenshotUri | ||||||
|  |       totalShotsMade | ||||||
|  |       totalShots | ||||||
|  |       makePercentage | ||||||
|  |       createdAt | ||||||
|  |       updatedAt | ||||||
|  |       startTime | ||||||
|  |       endTime | ||||||
|  |       elapsedTime | ||||||
|  |       screenshotUri | ||||||
|  |       stream { | ||||||
|  |         id | ||||||
|  |         isCompleted | ||||||
|  |       } | ||||||
|  |       tableSize | ||||||
|  |       tags { | ||||||
|  |         tagClasses { | ||||||
|  |           name | ||||||
|  |         } | ||||||
|  |         name | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     pageInfo { | ||||||
|  |       hasNextPage | ||||||
|  |       endCursor | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								src/operations/make_percentage_time_series.gql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/operations/make_percentage_time_series.gql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | query GetVideoMakePercentageIntervals($videoId: ID!, $intervalDuration: Int!) { | ||||||
|  |   getVideoMakePercentageIntervals( | ||||||
|  |     videoId: $videoId | ||||||
|  |     intervalDuration: $intervalDuration | ||||||
|  |   ) { | ||||||
|  |     makePercentage | ||||||
|  |     elapsedTime | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,30 +1,156 @@ | |||||||
| query GetShots( | query GetSerializedShotPaths($filterInput: FilterInput!) { | ||||||
| 	$filterInput: FilterInput |   getShots(filterInput: $filterInput) { | ||||||
| 	$includeCueObjectDistance: Boolean! = false |     id | ||||||
| 	$includeCueObjectAngle: Boolean! = false |     videoId | ||||||
| 	$includeCueBallSpeed: Boolean! = false |     startFrame | ||||||
| 	$includeShotDirection: Boolean! = false |     endFrame | ||||||
| 	$includeTargetPocketDistance: Boolean! = false |     serializedShotPaths { | ||||||
| 	$includeMake: Boolean! = false |       b64EncodedBuffer | ||||||
| 	$includeIntendedPocketType: Boolean! = false |     } | ||||||
| ) { |   } | ||||||
| 	getShots(filterInput: $filterInput) { | } | ||||||
| 		id |  | ||||||
| 		videoId | query GetShotAnnotationTypes { | ||||||
| 		startFrame |   getShotAnnotationTypes { | ||||||
| 		endFrame |     id | ||||||
| 		createdAt |     name | ||||||
| 		updatedAt |   } | ||||||
| 		cueObjectFeatures { | } | ||||||
| 			cueObjectDistance @include(if: $includeCueObjectDistance) |  | ||||||
| 			cueObjectAngle @include(if: $includeCueObjectAngle) | mutation UpdateShotAnnotations( | ||||||
| 			cueBallSpeed @include(if: $includeCueBallSpeed) |   $shotId: Int! | ||||||
| 			shotDirection @include(if: $includeShotDirection) |   $annotations: [UpdateAnnotationInputGQL!]! | ||||||
| 		} | ) { | ||||||
| 		pocketingIntentionFeatures { |   updateShotAnnotations(shotId: $shotId, annotations: $annotations) { | ||||||
| 			targetPocketDistance @include(if: $includeTargetPocketDistance) |     shot { | ||||||
| 			make @include(if: $includeMake) |       id | ||||||
| 			intendedPocketType @include(if: $includeIntendedPocketType) |       annotations { | ||||||
| 		} |         shotId | ||||||
| 	} |         type { | ||||||
|  |           id | ||||||
|  |           name | ||||||
|  |         } | ||||||
|  |         notes | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     error { | ||||||
|  |       shotId | ||||||
|  |       msg | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetShotsWithVideoGql( | ||||||
|  |   $filterInput: FilterInput! | ||||||
|  |   $shotsOrdering: GetShotsOrdering | ||||||
|  |   $limit: Int | ||||||
|  | ) { | ||||||
|  |   getOrderedShots( | ||||||
|  |     filterInput: $filterInput | ||||||
|  |     shotsOrdering: $shotsOrdering | ||||||
|  |     limit: $limit | ||||||
|  |   ) { | ||||||
|  |     shots { | ||||||
|  |       id | ||||||
|  |       videoId | ||||||
|  |       video { | ||||||
|  |         screenshotUri | ||||||
|  |         endTime | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ## Reserved for playlists (which are created from a filter) | ||||||
|  | query GetShotsWithMetadataFilterResult( | ||||||
|  |   $filterInput: FilterInput! | ||||||
|  |   $shotsOrdering: GetShotsOrdering | ||||||
|  |   $limit: Int | ||||||
|  |   $ids: [Int!] | ||||||
|  | ) { | ||||||
|  |   getOrderedShots( | ||||||
|  |     filterInput: $filterInput | ||||||
|  |     shotsOrdering: $shotsOrdering | ||||||
|  |     limit: $limit | ||||||
|  |     ids: $ids | ||||||
|  |   ) { | ||||||
|  |     count | ||||||
|  |     shots { | ||||||
|  |       ...ShotWithAllFeatures | ||||||
|  |     } | ||||||
|  |     ids | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # TODO: Delete | ||||||
|  | query GetShotsWithMetadata( | ||||||
|  |   $filterInput: FilterInput! | ||||||
|  |   $shotsPagination: GetShotsPagination | ||||||
|  |   $limit: Int | ||||||
|  |   $ids: [Int!] | ||||||
|  | ) { | ||||||
|  |   getShotsWithMetadata( | ||||||
|  |     filterInput: $filterInput | ||||||
|  |     shotsPagination: $shotsPagination | ||||||
|  |     limit: $limit | ||||||
|  |     ids: $ids | ||||||
|  |   ) { | ||||||
|  |     count | ||||||
|  |     shots { | ||||||
|  |       ...ShotWithAllFeatures | ||||||
|  |     } | ||||||
|  |     ids | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetShotsByIds($ids: [Int!]!) { | ||||||
|  |   getShotsByIds(ids: $ids) { | ||||||
|  |     ...ShotWithAllFeatures | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment ShotWithAllFeatures on ShotGQL { | ||||||
|  |   id | ||||||
|  |   videoId | ||||||
|  |   startFrame | ||||||
|  |   endFrame | ||||||
|  |   startTime @client | ||||||
|  |   endTime @client | ||||||
|  |   user { | ||||||
|  |     id | ||||||
|  |   } | ||||||
|  |   falsePositiveScore | ||||||
|  |   createdAt | ||||||
|  |   updatedAt | ||||||
|  |   cueObjectFeatures { | ||||||
|  |     cueObjectDistance | ||||||
|  |     cueObjectAngle | ||||||
|  |     cueBallSpeed | ||||||
|  |     shotDirection | ||||||
|  |     spinType | ||||||
|  |   } | ||||||
|  |   pocketingIntentionFeatures { | ||||||
|  |     make | ||||||
|  |     targetPocketDistance | ||||||
|  |     targetPocketAngle | ||||||
|  |     targetPocketAngleDirection | ||||||
|  |     marginOfErrorInDegrees | ||||||
|  |     intendedPocketType | ||||||
|  |   } | ||||||
|  |   pocketingIntentionInfo { | ||||||
|  |     ballId | ||||||
|  |     pocketId | ||||||
|  |     pathMetadataIndex | ||||||
|  |   } | ||||||
|  |   serializedShotPaths { | ||||||
|  |     b64EncodedBuffer | ||||||
|  |   } | ||||||
|  |   annotations { | ||||||
|  |     shotId | ||||||
|  |     type { | ||||||
|  |       id | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     notes | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										127
									
								
								src/operations/user.gql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								src/operations/user.gql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | |||||||
|  | mutation getProfileImageUploadLink($fileExt: String = ".png") { | ||||||
|  |   getProfileImageUploadLink(fileExt: $fileExt) { | ||||||
|  |     value { | ||||||
|  |       ... on UploadLink { | ||||||
|  |         uploadUrl | ||||||
|  |         headers { | ||||||
|  |           key | ||||||
|  |           value | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       ... on GetProfileUploadLinkErrors { | ||||||
|  |         error { | ||||||
|  |           ... on TooManyProfileImageUploadsErr { | ||||||
|  |             linksRequested | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mutation editProfileImageUri($profileImageUri: String!) { | ||||||
|  |   editProfileImageUri(profileImageUri: $profileImageUri) { | ||||||
|  |     id | ||||||
|  |     firebaseUid | ||||||
|  |     username | ||||||
|  |     profileImageUri | ||||||
|  |     createdAt | ||||||
|  |     updatedAt | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query getLoggedInUser { | ||||||
|  |   getLoggedInUser { | ||||||
|  |     id | ||||||
|  |     firebaseUid | ||||||
|  |     username | ||||||
|  |     isAdmin | ||||||
|  |     profileImageUri | ||||||
|  |     fargoRating | ||||||
|  |     activeVideoId | ||||||
|  |     createdAt | ||||||
|  |     updatedAt | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetUserPlayTime($userId: Int!) { | ||||||
|  |   getPlayTime(userId: $userId) { | ||||||
|  |     totalSeconds | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query getUsernames( | ||||||
|  |   $matchString: String! | ||||||
|  |   $limit: Int = null | ||||||
|  |   $after: String = null | ||||||
|  | ) { | ||||||
|  |   getUsernames(matchString: $matchString, limit: $limit, after: $after) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query getUserRelationshipsMatching( | ||||||
|  |   $userId: Int! | ||||||
|  |   $matchString: String! | ||||||
|  |   $limit: Int = null | ||||||
|  |   $after: String = null | ||||||
|  | ) { | ||||||
|  |   getUserRelationshipsMatching( | ||||||
|  |     userId: $userId | ||||||
|  |     matchString: $matchString | ||||||
|  |     limit: $limit | ||||||
|  |     after: $after | ||||||
|  |   ) { | ||||||
|  |     relationships { | ||||||
|  |       toUser { | ||||||
|  |         username | ||||||
|  |         id | ||||||
|  |       } | ||||||
|  |       toUserFollows | ||||||
|  |       toUserIsFollowedBy | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetUserTags { | ||||||
|  |   getUserTags { | ||||||
|  |     id | ||||||
|  |     name | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mutation followUser($followedUserId: Int!) { | ||||||
|  |   followUser(followedUserId: $followedUserId) { | ||||||
|  |     username | ||||||
|  |     following { | ||||||
|  |       id | ||||||
|  |     } | ||||||
|  |     followers { | ||||||
|  |       id | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mutation unfollowUser($followedUserId: Int!) { | ||||||
|  |   unfollowUser(followedUserId: $followedUserId) { | ||||||
|  |     username | ||||||
|  |     following { | ||||||
|  |       id | ||||||
|  |     } | ||||||
|  |     followers { | ||||||
|  |       id | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query getUserFollowingFollowers { | ||||||
|  |   getLoggedInUser { | ||||||
|  |     id | ||||||
|  |     following { | ||||||
|  |       id | ||||||
|  |       username | ||||||
|  |     } | ||||||
|  |     followers { | ||||||
|  |       id | ||||||
|  |       username | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										290
									
								
								src/operations/video.gql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								src/operations/video.gql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,290 @@ | |||||||
|  | query GetStreamMonitoringDetails($videoId: Int!, $debuggingJson: JSON) { | ||||||
|  |   getVideo(videoId: $videoId, debuggingJson: $debuggingJson) { | ||||||
|  |     id | ||||||
|  |     totalShots | ||||||
|  |     makePercentage | ||||||
|  |     elapsedTime | ||||||
|  |     currentHomography { | ||||||
|  |       crop { | ||||||
|  |         left | ||||||
|  |         top | ||||||
|  |         width | ||||||
|  |         height | ||||||
|  |       } | ||||||
|  |       pockets { | ||||||
|  |         left | ||||||
|  |         top | ||||||
|  |         width | ||||||
|  |         height | ||||||
|  |       } | ||||||
|  |       sourcePoints { | ||||||
|  |         topLeft { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         topSide { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         topRight { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         bottomLeft { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         bottomSide { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         bottomRight { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     stream { | ||||||
|  |       id | ||||||
|  |       linksRequested | ||||||
|  |       uploadsCompleted | ||||||
|  |       segmentProcessingCursor | ||||||
|  |       isCompleted | ||||||
|  |       uploadCompletionCursor | ||||||
|  |       lastIntendedSegmentBound | ||||||
|  |       initPlaylistUploadStatus | ||||||
|  |     } | ||||||
|  |     currentProcessing { | ||||||
|  |       errors { | ||||||
|  |         message | ||||||
|  |         startSegmentIndex | ||||||
|  |         endSegmentIndex | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetVideoUpdatePageDetails($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     id | ||||||
|  |     name | ||||||
|  |     totalShots | ||||||
|  |     makePercentage | ||||||
|  |     elapsedTime | ||||||
|  |     tableSize | ||||||
|  |     tags { | ||||||
|  |       tagClasses { | ||||||
|  |         name | ||||||
|  |       } | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mutation DeleteVideo($videoId: Int!) { | ||||||
|  |   deleteVideo(videoId: $videoId) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetVideoDetails($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     id | ||||||
|  |     name | ||||||
|  |     screenshotUri | ||||||
|  |     averageTimeBetweenShots | ||||||
|  |     elapsedTime | ||||||
|  |     endTime | ||||||
|  |     makePercentage | ||||||
|  |     medianRun | ||||||
|  |     startTime | ||||||
|  |     totalShots | ||||||
|  |     totalShotsMade | ||||||
|  |     createdAt | ||||||
|  |     updatedAt | ||||||
|  |     tableSize | ||||||
|  |     owner { | ||||||
|  |       id | ||||||
|  |       firebaseUid | ||||||
|  |       username | ||||||
|  |       profileImageUri | ||||||
|  |     } | ||||||
|  |     tags { | ||||||
|  |       tagClasses { | ||||||
|  |         name | ||||||
|  |       } | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetVideos($videoIds: [Int!]!) { | ||||||
|  |   getVideos(videoIds: $videoIds) { | ||||||
|  |     ...VideoStreamMetadata | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment VideoStreamMetadata on VideoGQL { | ||||||
|  |   id | ||||||
|  |   framesPerSecond | ||||||
|  |   stream { | ||||||
|  |     id | ||||||
|  |     streamSegmentType | ||||||
|  |     segments { | ||||||
|  |       uploaded | ||||||
|  |       valid | ||||||
|  |       segmentIndex | ||||||
|  |       endFrameIndex | ||||||
|  |       framesPerSecond | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   playlist { | ||||||
|  |     segmentDurations | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetVideoForShotTime($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     ...VideoStreamMetadata | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetVideo($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     id | ||||||
|  |     playlist { | ||||||
|  |       segmentDurations | ||||||
|  |     } | ||||||
|  |     homographyHistory { | ||||||
|  |       frameIndex | ||||||
|  |       crop { | ||||||
|  |         left | ||||||
|  |         top | ||||||
|  |         width | ||||||
|  |         height | ||||||
|  |       } | ||||||
|  |       pockets { | ||||||
|  |         left | ||||||
|  |         top | ||||||
|  |         width | ||||||
|  |         height | ||||||
|  |       } | ||||||
|  |       sourcePoints { | ||||||
|  |         topLeft { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         topSide { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         topRight { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         bottomLeft { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         bottomSide { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |         bottomRight { | ||||||
|  |           x | ||||||
|  |           y | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     stream { | ||||||
|  |       id | ||||||
|  |       streamSegmentType | ||||||
|  |       segments { | ||||||
|  |         segmentIndex | ||||||
|  |         endFrameIndex | ||||||
|  |         framesPerSecond | ||||||
|  |       } | ||||||
|  |       resolution { | ||||||
|  |         width | ||||||
|  |         height | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetAverageTimePerShotForVideo($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     id | ||||||
|  |     averageTimeBetweenShots | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetElapsedTimeForVideo($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     id | ||||||
|  |     elapsedTime | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetMedianRunForVideo($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     id | ||||||
|  |     medianRun | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment StreamWithEndFrames on UploadStreamGQL { | ||||||
|  |   id | ||||||
|  |   streamSegmentType | ||||||
|  |   segmentEndFrames @client | ||||||
|  |   resolution { | ||||||
|  |     width | ||||||
|  |     height | ||||||
|  |   } | ||||||
|  |   segments { | ||||||
|  |     uploaded | ||||||
|  |     valid | ||||||
|  |     segmentIndex | ||||||
|  |     endFrameIndex | ||||||
|  |     framesPerSecond | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment SegmentEndFrames on SegmentEndFramesGQL { | ||||||
|  |   id | ||||||
|  |   segmentEndFrames | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment SegmentStartTimes on SegmentStartTimesGQL { | ||||||
|  |   id | ||||||
|  |   segmentStartTimes | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment PlaylistWithSegmentStartTimes on HLSPlaylistGQL { | ||||||
|  |   videoId | ||||||
|  |   segmentDurations | ||||||
|  |   segmentStartTimes @client | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fragment VideoDurationData on VideoGQL { | ||||||
|  |   id | ||||||
|  |   framesPerSecond | ||||||
|  |   playlist { | ||||||
|  |     ...PlaylistWithSegmentStartTimes | ||||||
|  |   } | ||||||
|  |   stream { | ||||||
|  |     ...StreamWithEndFrames | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetVideoForClipTimes($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     ...VideoDurationData | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetHeaderInfoByVideoId($videoId: Int!) { | ||||||
|  |   getVideo(videoId: $videoId) { | ||||||
|  |     id | ||||||
|  |     name | ||||||
|  |     startTime | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,40 +1,126 @@ | |||||||
| mutation CreateUploadStream( | mutation CreateUploadStream($videoMetadataInput: VideoMetadataInput!) { | ||||||
|   $videoName: String!, |   createUploadStream(videoMetadata: $videoMetadataInput) { | ||||||
|   $deviceType: DeviceTypeEnum, |  | ||||||
|   $osVersion: String, |  | ||||||
|   $appVersion: String, |  | ||||||
|   $browserName: String, |  | ||||||
|   $browserVersion: String, |  | ||||||
|   $locale: String, |  | ||||||
|   $timezone: String, |  | ||||||
|   $networkType: String, |  | ||||||
|   $ipAddress: String |  | ||||||
| ) { |  | ||||||
|   createUploadStream( |  | ||||||
|     videoName: $videoName |  | ||||||
|     uploadMetadata: { |  | ||||||
|       deviceType: $deviceType |  | ||||||
|       osVersion: $osVersion |  | ||||||
|       appVersion: $appVersion |  | ||||||
|       browserName: $browserName |  | ||||||
|       browserVersion: $browserVersion |  | ||||||
|       locale: $locale |  | ||||||
|       timezone: $timezone |  | ||||||
|       networkType: $networkType |  | ||||||
|       ipAddress: $ipAddress |  | ||||||
|     } |  | ||||||
|   ) { |  | ||||||
|     videoId |     videoId | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| mutation GetUploadLink($videoId: Int!, $chunkIndex: Int!) { | mutation GetUploadLink($videoId: Int!, $segmentIndex: Int!) { | ||||||
|   getUploadLink(videoId: $videoId, chunkIndex: $chunkIndex) { |   getUploadLink(videoId: $videoId, segmentIndex: $segmentIndex) { | ||||||
|     uploadUrl |     value { | ||||||
|     linksRequested |       ... on UploadLink { | ||||||
|  |         uploadUrl | ||||||
|  |         headers { | ||||||
|  |           key | ||||||
|  |           value | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       ... on GetUploadLinkErrors { | ||||||
|  |         error { | ||||||
|  |           ... on MustHaveSetForUploadLinkErr { | ||||||
|  |             resolution | ||||||
|  |             framesPerSecond | ||||||
|  |           } | ||||||
|  |           ... on SegmentAlreadyUploadedErr { | ||||||
|  |             segmentId | ||||||
|  |           } | ||||||
|  |           ... on ProcessingFailedErr { | ||||||
|  |             processing { | ||||||
|  |               status | ||||||
|  |               errors { | ||||||
|  |                 message | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     stream { | ||||||
|  |       uploadCompletionCursor | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| mutation TerminateUploadStream($videoId: Int!) { | mutation GetHlsInitUploadLink($videoId: Int!) { | ||||||
|   terminateUploadStream(videoId: $videoId)  |   getHlsInitUploadLink(videoId: $videoId) { | ||||||
|  |     value { | ||||||
|  |       ... on UploadLink { | ||||||
|  |         uploadUrl | ||||||
|  |         headers { | ||||||
|  |           key | ||||||
|  |           value | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       ... on GetUploadLinkErrors { | ||||||
|  |         error { | ||||||
|  |           ... on NoInitForChunkedUploadErr { | ||||||
|  |             segmentType | ||||||
|  |           } | ||||||
|  |           ... on InitUploadAlreadyCompletedErr { | ||||||
|  |             segmentType | ||||||
|  |           } | ||||||
|  |           ... on TooManyInitUploadsErr { | ||||||
|  |             linksRequested | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mutation SetSegmentDuration( | ||||||
|  |   $videoId: Int! | ||||||
|  |   $segmentIndex: Int! | ||||||
|  |   $duration: Float! | ||||||
|  | ) { | ||||||
|  |   setSegmentDuration( | ||||||
|  |     videoId: $videoId | ||||||
|  |     segmentIndex: $segmentIndex | ||||||
|  |     duration: $duration | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mutation EditUploadStream( | ||||||
|  |   $videoId: Int! | ||||||
|  |   $videoMetadataInput: VideoMetadataInput! | ||||||
|  | ) { | ||||||
|  |   editUploadStream(videoId: $videoId, videoMetadata: $videoMetadataInput) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | query GetUploadStreams( | ||||||
|  |   $limit: Int! = 5 | ||||||
|  |   $after: String = null | ||||||
|  |   $filters: VideoFilterInput = null | ||||||
|  | ) { | ||||||
|  |   getUserVideos(limit: $limit, after: $after, filters: $filters) { | ||||||
|  |     videos { | ||||||
|  |       id | ||||||
|  |     } | ||||||
|  |     pageInfo { | ||||||
|  |       hasNextPage | ||||||
|  |       endCursor | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | query GetUploadStreamsWithDetails( | ||||||
|  |   $limit: Int! = 5 | ||||||
|  |   $after: String = null | ||||||
|  |   $filters: VideoFilterInput = null | ||||||
|  | ) { | ||||||
|  |   getUserVideos(limit: $limit, after: $after, filters: $filters) { | ||||||
|  |     videos { | ||||||
|  |       id | ||||||
|  |       name | ||||||
|  |       startTime | ||||||
|  |       stream { | ||||||
|  |         isCompleted | ||||||
|  |         lastIntendedSegmentBound | ||||||
|  |         uploadCompletionCursor | ||||||
|  |         uploadsCompleted | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     pageInfo { | ||||||
|  |       hasNextPage | ||||||
|  |       endCursor | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										808
									
								
								src/schema.gql
									
									
									
									
									
								
							
							
						
						
									
										808
									
								
								src/schema.gql
									
									
									
									
									
								
							| @@ -1,31 +1,103 @@ | |||||||
| type Query { | type Query { | ||||||
|   getAggregateShots(bucketSets: [BucketSetInputGQL!]!): [AggregateResultGQL!]! |   getAggregatedShotMetrics( | ||||||
|   getUser(userId: Int!): UserGQL |     aggregateInput: AggregateInputGQL! | ||||||
|   getVideo(videoId: Int!): VideoGQL! |   ): [AggregateResultGQL!]! | ||||||
|   getShots(filterInput: FilterInput = null): [ShotGQL!]! |  | ||||||
|   getBucketSet(keyName: String!): BucketSetGQL |   getBucketSet(keyName: String!): BucketSetGQL | ||||||
|  |   getDeployedConfig: DeployedConfigGQL! | ||||||
|  |   waitFor(duration: Float!): Float! | ||||||
|  |   getVideoMakePercentageIntervals( | ||||||
|  |     videoId: ID! | ||||||
|  |     intervalDuration: Int! = 300 | ||||||
|  |   ): [MakePercentageIntervalGQL!]! | ||||||
|  |   getOrderedShots( | ||||||
|  |     filterInput: FilterInput! | ||||||
|  |     ids: [Int!] = null | ||||||
|  |     shotsOrdering: GetShotsOrdering = null | ||||||
|  |     limit: Int! = 500 | ||||||
|  |   ): GetShotsResult! | ||||||
|  |   getShotsWithMetadata( | ||||||
|  |     filterInput: FilterInput! | ||||||
|  |     ids: [Int!] = null | ||||||
|  |     shotsPagination: GetShotsPagination = null | ||||||
|  |     limit: Int! = 500 | ||||||
|  |   ): GetShotsResult! | ||||||
|  |   getShots( | ||||||
|  |     filterInput: FilterInput! | ||||||
|  |     shotsPagination: GetShotsPagination = null | ||||||
|  |     limit: Int! = 500 | ||||||
|  |   ): [ShotGQL!]! | ||||||
|  |   getShotsByIds(ids: [Int!]!): [ShotGQL!]! | ||||||
|  |   getShotAnnotationTypes(errorTypes: Boolean = false): [ShotAnnotationTypeGQL!]! | ||||||
|  |   getUser(userId: Int!): UserGQL | ||||||
|  |   getLoggedInUser: UserGQL | ||||||
|  |   getUsernames( | ||||||
|  |     matchString: String = null | ||||||
|  |     limit: Int = null | ||||||
|  |     after: String = null | ||||||
|  |   ): [String!]! | ||||||
|  |   getUserRelationshipsMatching( | ||||||
|  |     userId: Int! | ||||||
|  |     matchString: String = null | ||||||
|  |     limit: Int = 100 | ||||||
|  |     after: String = null | ||||||
|  |   ): UserRelationshipsResult! | ||||||
|  |   getPlayTime(userId: Int!): UserPlayTimeGQL! | ||||||
|  |   getUserVideos( | ||||||
|  |     userId: Int = null | ||||||
|  |     limit: Int! = 5 | ||||||
|  |     after: String = null | ||||||
|  |     filters: VideoFilterInput = null | ||||||
|  |   ): VideoHistoryGQL! | ||||||
|  |   getUserTags: [TagGQL!]! | ||||||
|  |   getVideo(videoId: Int!, debuggingJson: JSON = null): VideoGQL! | ||||||
|  |   getVideos(videoIds: [Int!]!): [VideoGQL!]! | ||||||
|  |   getFeedVideos( | ||||||
|  |     limit: Int! = 5 | ||||||
|  |     after: String = null | ||||||
|  |     filters: VideoFilterInput = null | ||||||
|  |   ): VideoHistoryGQL! | ||||||
| } | } | ||||||
|  |  | ||||||
| type AggregateResultGQL { | type AggregateResultGQL { | ||||||
|   featureBuckets: [BucketGQL!]! |   aggregationIdentifiers: [AggregationIdentifierGQL!]! | ||||||
|   targetMetrics: [TargetMetricGQL!]! |   targetMetrics: TargetMetricsGQL! | ||||||
| } | } | ||||||
|  |  | ||||||
| type BucketGQL { | type AggregationIdentifierGQL { | ||||||
|   rangeKey: String! |  | ||||||
|   lowerBound: Float! |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type TargetMetricGQL { |  | ||||||
|   count: Int |  | ||||||
|   makePercentage: Float |  | ||||||
|   floatFeature: TargetFloatFeatureGQL |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type TargetFloatFeatureGQL { |  | ||||||
|   featureName: String! |   featureName: String! | ||||||
|   average: Float |   groupName: String! | ||||||
|   median: Float | } | ||||||
|  |  | ||||||
|  | type TargetMetricsGQL { | ||||||
|  |   count: Int! | ||||||
|  |   makePercentage: Float | ||||||
|  |   averageDifficulty: Float | ||||||
|  |   spinTypeCounts: SpinTypeCountsGQL | ||||||
|  |   shotDirectionCounts: ShotDirectionCountsGQL | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type SpinTypeCountsGQL { | ||||||
|  |   follow: Int! | ||||||
|  |   draw: Int! | ||||||
|  |   center: Int! | ||||||
|  |   unknown: Int! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type ShotDirectionCountsGQL { | ||||||
|  |   left: Int! | ||||||
|  |   right: Int! | ||||||
|  |   straight: Int! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input AggregateInputGQL { | ||||||
|  |   aggregations: [AggregationInput!]! | ||||||
|  |   filterInput: FilterInput | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input AggregationInput @oneOf { | ||||||
|  |   bucketSet: BucketSetInputGQL | ||||||
|  |   enum: EnumAggregation | ||||||
|  |   datetimeRange: DatetimeRangeAggregationInput | ||||||
| } | } | ||||||
|  |  | ||||||
| input BucketSetInputGQL { | input BucketSetInputGQL { | ||||||
| @@ -38,67 +110,91 @@ input BucketInputGQL { | |||||||
|   lowerBound: Float! |   lowerBound: Float! | ||||||
| } | } | ||||||
|  |  | ||||||
| type UserGQL { | input EnumAggregation { | ||||||
|   id: Int! |   feature: String! | ||||||
|   username: String! |  | ||||||
|   createdAt: DateTime |  | ||||||
|   updatedAt: DateTime |  | ||||||
|   statistics: UserStatisticsGQL! |  | ||||||
| } | } | ||||||
|  |  | ||||||
| """Date with time (isoformat)""" | input DatetimeRangeAggregationInput { | ||||||
|  |   startDatetime: DateTime = null | ||||||
|  |   endDatetime: DateTime = null | ||||||
|  |   interval: TimeInterval! | ||||||
|  |   feature: String! = "created_at" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | """ | ||||||
|  | Date with time (isoformat) | ||||||
|  | """ | ||||||
| scalar DateTime | scalar DateTime | ||||||
|  |  | ||||||
| type UserStatisticsGQL { | input TimeInterval @oneOf { | ||||||
|   totalShots: Int! |   timedelta: TimeDeltaGQL | ||||||
|   totalShotsMade: Int! |   aligned: AlignedIntervalEnum | ||||||
|   makePercentage: Decimal! |  | ||||||
|   averageTimeBetweenShots: Decimal! |  | ||||||
|   timeSpentPlaying: Decimal! |  | ||||||
|   medianRun: Decimal |  | ||||||
| } | } | ||||||
|  |  | ||||||
| """Decimal (fixed-point)""" | input TimeDeltaGQL { | ||||||
| scalar Decimal |   days: Int = 0 | ||||||
|  |   weeks: Int = 0 | ||||||
| type VideoGQL { |   months: Int = 0 | ||||||
|   id: Int! |   years: Int = 0 | ||||||
|   totalShotsMade: Int! |  | ||||||
|   totalShots: Int! |  | ||||||
|   makePercentage: Decimal! |  | ||||||
|   medianRun: Decimal! |  | ||||||
|   averageTimeBetweenShots: Decimal |  | ||||||
|   createdAt: DateTime! |  | ||||||
|   updatedAt: DateTime! |  | ||||||
|   shots: [ShotGQL!]! |  | ||||||
|   startTime: DateTime! |  | ||||||
|   endTime: DateTime! |  | ||||||
|   elapsedTime: Decimal! |  | ||||||
|   framesPerSecond: Int! |  | ||||||
|   totalFrames: Int! |  | ||||||
|   stream: UploadStreamGQL |  | ||||||
| } | } | ||||||
|  |  | ||||||
| type ShotGQL { | enum AlignedIntervalEnum { | ||||||
|   id: Int |   MONTH | ||||||
|   videoId: Int |   YEAR | ||||||
|   startFrame: Int |   WEEK | ||||||
|   endFrame: Int |   DAY | ||||||
|   createdAt: DateTime |  | ||||||
|   updatedAt: DateTime |  | ||||||
|   features: ShotFeaturesGQL |  | ||||||
|   cueObjectFeatures: CueObjectFeaturesGQL |  | ||||||
|   pocketingIntentionFeatures: PocketingIntentionFeaturesGQL |  | ||||||
| } | } | ||||||
|  |  | ||||||
| type ShotFeaturesGQL { | input FilterInput @oneOf { | ||||||
|   cueObjectAngle: Float |   andFilters: [FilterInput!] | ||||||
|   cueObjectDistance: Float |   orFilters: [FilterInput!] | ||||||
|   targetPocketDistance: Float |   notFilter: FilterInput | ||||||
|   intendedPocket: PocketEnum |   cueObjectDistance: FloatRangeFilter | ||||||
|   cueBallSpeed: Float |   targetPocketDistance: FloatRangeFilter | ||||||
|   shotDirection: ShotDirectionEnum |   cueObjectAngle: FloatRangeFilter | ||||||
|   bank: BankFeaturesGQL |   cueBallSpeed: FloatRangeFilter | ||||||
|  |   difficulty: FloatRangeFilter | ||||||
|  |   intendedPocketType: [PocketEnum!] | ||||||
|  |   shotDirection: [ShotDirectionEnum!] | ||||||
|  |   videoId: [Int!] | ||||||
|  |   userId: [Int!] | ||||||
|  |   username: [String!] | ||||||
|  |   fargoRating: FloatRangeFilter | ||||||
|  |   make: [Boolean!] | ||||||
|  |   tags: [VideoTagInput!] | ||||||
|  |   annotations: [ShotAnnotationInput!] | ||||||
|  |   isStraight: [Boolean!] | ||||||
|  |   isRight: [Boolean!] | ||||||
|  |   isLeft: [Boolean!] | ||||||
|  |   isLeftMiss: [Boolean!] | ||||||
|  |   isRightMiss: [Boolean!] | ||||||
|  |   isDirect: [Boolean!] | ||||||
|  |   tableSize: FloatRangeFilter | ||||||
|  |   bankAngle: FloatRangeFilter | ||||||
|  |   bankDistance: FloatRangeFilter | ||||||
|  |   kickAngle: FloatRangeFilter | ||||||
|  |   kickDistance: FloatRangeFilter | ||||||
|  |   cueAngleAfterObject: FloatRangeFilter | ||||||
|  |   spinType: [SpinTypeEnum!] | ||||||
|  |   cueSpeedAfterObject: FloatRangeFilter | ||||||
|  |   falsePositiveScore: FloatRangeFilter | ||||||
|  |   backcut: [Boolean!] | ||||||
|  |   targetPocketAngleDirection: [ShotDirectionEnum!] | ||||||
|  |   targetPocketAngle: FloatRangeFilter | ||||||
|  |   missAngleInDegrees: FloatRangeFilter | ||||||
|  |   marginOfErrorInDegrees: FloatRangeFilter | ||||||
|  |   createdAt: DateRangeFilter | ||||||
|  |   totalDistance: FloatRangeFilter | ||||||
|  |   runLength: FloatRangeFilter | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input FloatRangeFilter { | ||||||
|  |   lessThan: Float = null | ||||||
|  |   greaterThanEqualTo: Float = null | ||||||
|  |   greaterThan: Float = null | ||||||
|  |   includeOnNone: Boolean! = false | ||||||
|  |   lessThanInclusive: Boolean! = false | ||||||
|  |   greaterThanInclusive: Boolean! = true | ||||||
| } | } | ||||||
|  |  | ||||||
| enum PocketEnum { | enum PocketEnum { | ||||||
| @@ -112,6 +208,122 @@ enum ShotDirectionEnum { | |||||||
|   STRAIGHT |   STRAIGHT | ||||||
| } | } | ||||||
|  |  | ||||||
|  | input VideoTagInput { | ||||||
|  |   tagClasses: [VideoTagClassInput!]! = [] | ||||||
|  |   name: String! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input VideoTagClassInput { | ||||||
|  |   name: String! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input ShotAnnotationInput { | ||||||
|  |   name: String! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | enum SpinTypeEnum { | ||||||
|  |   DRAW | ||||||
|  |   FOLLOW | ||||||
|  |   CENTER | ||||||
|  |   UNKNOWN | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input DateRangeFilter { | ||||||
|  |   lessThan: Date = null | ||||||
|  |   greaterThanEqualTo: Date = null | ||||||
|  |   greaterThan: Date = null | ||||||
|  |   includeOnNone: Boolean! = false | ||||||
|  |   lessThanInclusive: Boolean! = false | ||||||
|  |   greaterThanInclusive: Boolean! = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | """ | ||||||
|  | Date (isoformat) | ||||||
|  | """ | ||||||
|  | scalar Date | ||||||
|  |  | ||||||
|  | type BucketSetGQL { | ||||||
|  |   keyName: String! | ||||||
|  |   feature: String! | ||||||
|  |   buckets: [BucketGQL!]! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type BucketGQL { | ||||||
|  |   rangeKey: String! | ||||||
|  |   lowerBound: Float! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type DeployedConfigGQL { | ||||||
|  |   allowNewUsers: Boolean! | ||||||
|  |   firebase: Boolean! | ||||||
|  |   devMode: Boolean! | ||||||
|  |   environment: String! | ||||||
|  |   minimumAllowedAppVersion: String! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type MakePercentageIntervalGQL { | ||||||
|  |   makePercentage: Float! | ||||||
|  |   elapsedTime: Float! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type GetShotsResult { | ||||||
|  |   shots: [ShotGQL!]! | ||||||
|  |   count: Int | ||||||
|  |   ids: [Int!]! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type ShotGQL { | ||||||
|  |   id: Int! | ||||||
|  |   videoId: Int! | ||||||
|  |   startFrame: Int! | ||||||
|  |   endFrame: Int! | ||||||
|  |   createdAt: DateTime | ||||||
|  |   updatedAt: DateTime | ||||||
|  |   cueObjectFeatures: CueObjectFeaturesGQL | ||||||
|  |   pocketingIntentionFeatures: PocketingIntentionFeaturesGQL | ||||||
|  |   pocketingIntentionInfo: PocketingIntentionInfoGQL | ||||||
|  |   bankFeatures: BankFeaturesGQL | ||||||
|  |   serializedShotPaths: SerializedShotPathsGQL | ||||||
|  |   user: UserGQL | ||||||
|  |   annotations: [ShotAnnotationGQL!]! | ||||||
|  |   falsePositiveScore: Float | ||||||
|  |   video: VideoGQL | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type CueObjectFeaturesGQL { | ||||||
|  |   cueObjectDistance: Float | ||||||
|  |   cueObjectAngle: Float | ||||||
|  |   cueBallSpeed: Float | ||||||
|  |   shotDirection: ShotDirectionEnum | ||||||
|  |   spinType: SpinTypeEnum | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type PocketingIntentionFeaturesGQL { | ||||||
|  |   targetPocketDistance: Float | ||||||
|  |   make: Boolean | ||||||
|  |   intendedPocketType: PocketEnum | ||||||
|  |   difficulty: Float | ||||||
|  |   targetPocketAngle: Float | ||||||
|  |   targetPocketAngleDirection: ShotDirectionEnum | ||||||
|  |   marginOfErrorInDegrees: Float | ||||||
|  |   backcut: Boolean | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type PocketingIntentionInfoGQL { | ||||||
|  |   ballId: Int! | ||||||
|  |   pocketId: PocketIdentifier! | ||||||
|  |   pathMetadataIndex: Int! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | enum PocketIdentifier { | ||||||
|  |   TOP_LEFT | ||||||
|  |   TOP_SIDE | ||||||
|  |   TOP_RIGHT | ||||||
|  |   BOTTOM_LEFT | ||||||
|  |   BOTTOM_SIDE | ||||||
|  |   BOTTOM_RIGHT | ||||||
|  | } | ||||||
|  |  | ||||||
| type BankFeaturesGQL { | type BankFeaturesGQL { | ||||||
|   wallsHit: [WallTypeEnum!]! |   wallsHit: [WallTypeEnum!]! | ||||||
|   bankAngle: Float! |   bankAngle: Float! | ||||||
| @@ -123,111 +335,300 @@ enum WallTypeEnum { | |||||||
|   SHORT |   SHORT | ||||||
| } | } | ||||||
|  |  | ||||||
| type CueObjectFeaturesGQL { | type SerializedShotPathsGQL { | ||||||
|   cueObjectDistance: Float |   b64EncodedBuffer: String | ||||||
|   cueObjectAngle: Float |  | ||||||
|   cueBallSpeed: Float |  | ||||||
|   shotDirection: ShotDirectionEnum |  | ||||||
| } | } | ||||||
|  |  | ||||||
| type PocketingIntentionFeaturesGQL { | type UserGQL { | ||||||
|   targetPocketDistance: Float |   id: Int! | ||||||
|   make: Boolean |   firebaseUid: String | ||||||
|   intendedPocketType: PocketEnum |   username: String! | ||||||
|  |   isAdmin: Boolean | ||||||
|  |   fargoRating: Int | ||||||
|  |   activeVideoId: Int | ||||||
|  |   profileImageUri: String | ||||||
|  |   createdAt: DateTime | ||||||
|  |   updatedAt: DateTime | ||||||
|  |   following: [UserGQL!] | ||||||
|  |   followers: [UserGQL!] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type ShotAnnotationGQL { | ||||||
|  |   shotId: Int! | ||||||
|  |   type: ShotAnnotationTypeGQL! | ||||||
|  |   creator: UserGQL! | ||||||
|  |   notes: String! | ||||||
|  |   errorDefault: Boolean! | ||||||
|  |   createdAt: DateTime | ||||||
|  |   updatedAt: DateTime | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type ShotAnnotationTypeGQL { | ||||||
|  |   id: Int! | ||||||
|  |   name: String! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type VideoGQL { | ||||||
|  |   id: Int! | ||||||
|  |   owner: UserGQL | ||||||
|  |   name: String | ||||||
|  |   screenshotUri: String | ||||||
|  |   totalShotsMade: Int! | ||||||
|  |   totalShots: Int! | ||||||
|  |   makePercentage: Float! | ||||||
|  |   medianRun: Float | ||||||
|  |   averageTimeBetweenShots: Float | ||||||
|  |   createdAt: DateTime | ||||||
|  |   updatedAt: DateTime | ||||||
|  |   shots: [ShotGQL!]! | ||||||
|  |   startTime: DateTime | ||||||
|  |   endTime: DateTime | ||||||
|  |   elapsedTime: Float | ||||||
|  |   framesPerSecond: Float! | ||||||
|  |   tableSize: Float! | ||||||
|  |   stream: UploadStreamGQL | ||||||
|  |   playlist: HLSPlaylistGQL | ||||||
|  |   tags: [VideoTag!]! | ||||||
|  |   currentHomography: HomographyInfoGQL | ||||||
|  |   homographyHistory: [HomographyInfoGQL!]! | ||||||
|  |   currentProcessing: VideoProcessingGQL | ||||||
| } | } | ||||||
|  |  | ||||||
| type UploadStreamGQL { | type UploadStreamGQL { | ||||||
|   id: ID! |   id: ID! | ||||||
|   linksRequested: Int! |   linksRequested: Int! | ||||||
|   uploadsCompleted: Int! |   uploadsCompleted: Int! | ||||||
|  |   segmentProcessingCursor: Int! | ||||||
|  |   lastIntendedSegmentBound: Int | ||||||
|   isCompleted: Boolean! |   isCompleted: Boolean! | ||||||
|   uploadMetadata: UploadStreamMetadata! |   initPlaylistUploadStatus: InitPlaylistUploadStatusEnum | ||||||
|  |   lowestUnuploadedSegmentIndex: Int! | ||||||
|  |   uploadCompletionCursor: Int! | ||||||
|  |   errors: [StreamErrorGQL!]! | ||||||
|   createdAt: DateTime! |   createdAt: DateTime! | ||||||
|   updatedAt: DateTime! |   updatedAt: DateTime! | ||||||
|  |   segments: [UploadSegmentGQL!]! | ||||||
|  |   resolution: VideoResolutionGQL! | ||||||
|  |   streamSegmentType: StreamSegmentTypeEnum! | ||||||
| } | } | ||||||
|  |  | ||||||
| type UploadStreamMetadata { | enum InitPlaylistUploadStatusEnum { | ||||||
|   deviceType: DeviceTypeEnum |   NOT_APPLICABLE | ||||||
|   osVersion: String |   NOT_UPLOADED | ||||||
|   appVersion: String |   UPLOADED | ||||||
|   browserName: String |  | ||||||
|   browserVersion: String |  | ||||||
|   locale: String |  | ||||||
|   timezone: String |  | ||||||
|   networkType: String |  | ||||||
|   ipAddress: String |  | ||||||
| } | } | ||||||
|  |  | ||||||
| enum DeviceTypeEnum { | type StreamErrorGQL { | ||||||
|   IOS |   message: String! | ||||||
|   ANDROID |  | ||||||
|   BROWSER |  | ||||||
| } | } | ||||||
|  |  | ||||||
| input FilterInput { | type UploadSegmentGQL { | ||||||
|   andFilters: AndFilter = null |   segmentIndex: Int! | ||||||
|   orFilters: OrFilter = null |   uploaded: Boolean! | ||||||
|   cueObjectDistance: CueObjectDistanceInput = null |   valid: Boolean! | ||||||
|   targetPocketDistance: TargetPocketDistanceInput = null |   endFrameIndex: Int | ||||||
|   cueObjectAngle: CueObjectAngleInput = null |   framesPerSecond: Float | ||||||
|   cueBallSpeed: CueBallSpeedInput = null |   durationInSeconds: Float | ||||||
|   intendedPocketType: IntendedPocketTypeInput = null |   linksRequested: Int! | ||||||
|   shotDirection: ShotDirectionInput = null |  | ||||||
| } | } | ||||||
|  |  | ||||||
| input AndFilter { | type VideoResolutionGQL { | ||||||
|   filters: [FilterInput!]! |   width: Int | ||||||
|  |   height: Int | ||||||
| } | } | ||||||
|  |  | ||||||
| input OrFilter { | enum StreamSegmentTypeEnum { | ||||||
|   filters: [FilterInput!]! |   FRAGMENTED_MP4 | ||||||
|  |   RB_CHUNKED_MP4 | ||||||
| } | } | ||||||
|  |  | ||||||
| input CueObjectDistanceInput { | type HLSPlaylistGQL { | ||||||
|   value: RangeFilter! |   videoId: Int! | ||||||
|  |   m3u8Text: String! | ||||||
|  |   segmentDurations: [Float!]! | ||||||
| } | } | ||||||
|  |  | ||||||
| input RangeFilter { | type VideoTag { | ||||||
|   lessThan: Float = null |   tagClasses: [VideoTagClass!]! | ||||||
|   greaterThanEqualTo: Float = null |   name: String! | ||||||
| } | } | ||||||
|  |  | ||||||
| input TargetPocketDistanceInput { | type VideoTagClass { | ||||||
|   value: RangeFilter! |   name: String! | ||||||
| } | } | ||||||
|  |  | ||||||
| input CueObjectAngleInput { | type HomographyInfoGQL { | ||||||
|   value: RangeFilter! |   frameIndex: Int! | ||||||
|  |   crop: BoundingBoxGQL! | ||||||
|  |   pockets: [BoundingBoxGQL!]! | ||||||
|  |   sourcePoints: PocketPointsGQL! | ||||||
|  |   destPoints: PocketPointsGQL! | ||||||
| } | } | ||||||
|  |  | ||||||
| input CueBallSpeedInput { | type BoundingBoxGQL { | ||||||
|   value: RangeFilter! |   left: Float! | ||||||
|  |   top: Float! | ||||||
|  |   width: Float! | ||||||
|  |   height: Float! | ||||||
| } | } | ||||||
|  |  | ||||||
| input IntendedPocketTypeInput { | type PocketPointsGQL { | ||||||
|   value: EnumFilter! |   topLeft: IntPoint2D! | ||||||
|  |   topSide: IntPoint2D! | ||||||
|  |   topRight: IntPoint2D! | ||||||
|  |   bottomLeft: IntPoint2D! | ||||||
|  |   bottomSide: IntPoint2D! | ||||||
|  |   bottomRight: IntPoint2D! | ||||||
| } | } | ||||||
|  |  | ||||||
| input EnumFilter { | type IntPoint2D { | ||||||
|   equals: String = null |   x: Int! | ||||||
|  |   y: Int! | ||||||
| } | } | ||||||
|  |  | ||||||
| input ShotDirectionInput { | type VideoProcessingGQL { | ||||||
|   value: EnumFilter! |   errors: [VideoProcessingErrorGQL!]! | ||||||
|  |   status: ProcessingStatusEnum! | ||||||
|  |   statuses: [VideoProcessingStatusGQL!]! | ||||||
| } | } | ||||||
|  |  | ||||||
| type BucketSetGQL { | type VideoProcessingErrorGQL { | ||||||
|   keyName: String! |   message: String! | ||||||
|   feature: String! |   startSegmentIndex: Int | ||||||
|   buckets: [BucketGQL!]! |   endSegmentIndex: Int | ||||||
| } | } | ||||||
|  |  | ||||||
|  | enum ProcessingStatusEnum { | ||||||
|  |   STARTED | ||||||
|  |   FAILED | ||||||
|  |   SUCCEEDED | ||||||
|  |   SUSPENDED | ||||||
|  |   CREATED | ||||||
|  |   QUEUED | ||||||
|  |   RUNNING | ||||||
|  |   REEXTRACTING_FEATURES | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type VideoProcessingStatusGQL { | ||||||
|  |   status: ProcessingStatusEnum! | ||||||
|  |   appVersion: String! | ||||||
|  |   sequenceId: Int! | ||||||
|  |   createdAt: DateTime | ||||||
|  |   updatedAt: DateTime | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input GetShotsOrdering { | ||||||
|  |   orderings: [ShotsOrderingComponent!]! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input ShotsOrderingComponent @oneOf { | ||||||
|  |   videoCreation: DatetimeShotOrdering | ||||||
|  |   marginOfError: FloatShotOrdering | ||||||
|  |   videoId: IntShotOrdering | ||||||
|  |   startFrame: IntShotOrdering | ||||||
|  |   runLength: IntShotOrdering | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input DatetimeShotOrdering { | ||||||
|  |   descending: Boolean! = true | ||||||
|  |   startingAt: DateTime = null | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input FloatShotOrdering { | ||||||
|  |   descending: Boolean! = true | ||||||
|  |   startingAt: Float = null | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input IntShotOrdering { | ||||||
|  |   descending: Boolean! = true | ||||||
|  |   startingAt: Int = null | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input GetShotsPagination { | ||||||
|  |   createdAfter: CreatedAfter! | ||||||
|  |   startFrameAfter: Int! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input CreatedAfter @oneOf { | ||||||
|  |   videoId: Int | ||||||
|  |   createdAt: DateTime | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type UserRelationshipsResult { | ||||||
|  |   inquiringUser: UserGQL! | ||||||
|  |   relationships: [UserRelationship!]! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type UserRelationship { | ||||||
|  |   toUser: UserGQL! | ||||||
|  |   toUserFollows: Boolean! | ||||||
|  |   toUserIsFollowedBy: Boolean! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type UserPlayTimeGQL { | ||||||
|  |   totalSeconds: Float! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type VideoHistoryGQL { | ||||||
|  |   videos: [VideoGQL!]! | ||||||
|  |   pageInfo: PageInfoGQL! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type PageInfoGQL { | ||||||
|  |   hasNextPage: Boolean! | ||||||
|  |   endCursor: String | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input VideoFilterInput { | ||||||
|  |   isStreamCompleted: Boolean = null | ||||||
|  |   requireCursorCompletion: Boolean! = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type TagGQL { | ||||||
|  |   name: String! | ||||||
|  |   id: Int! | ||||||
|  |   group: String | ||||||
|  | } | ||||||
|  |  | ||||||
|  | """ | ||||||
|  | The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf). | ||||||
|  | """ | ||||||
|  | scalar JSON | ||||||
|  |   @specifiedBy( | ||||||
|  |     url: "https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf" | ||||||
|  |   ) | ||||||
|  |  | ||||||
| type Mutation { | type Mutation { | ||||||
|   createBucketSet(params: CreateBucketSetInput!): BucketSetGQL! |   createBucketSet(params: CreateBucketSetInput!): BucketSetGQL! | ||||||
|   processVideoSource(input: ProcessVideoSourceInput!): ProcessVideoSourceReturn! |   setLoggerLevel(path: String!, level: String!): Boolean! | ||||||
|   createUploadStream(uploadMetadata: UploadMetadataInput, videoName: String = null): CreateUploadStreamReturn! |   addAnnotationToShot( | ||||||
|   getUploadLink(videoId: Int!, chunkIndex: Int!): GetUploadLinkReturn! |     shotId: Int! | ||||||
|   terminateUploadStream(videoId: Int!): Boolean! |     annotationName: String! | ||||||
|  |     notes: String = null | ||||||
|  |   ): AddShotAnnotationReturn! | ||||||
|  |   updateShotAnnotations( | ||||||
|  |     shotId: Int! | ||||||
|  |     annotations: [UpdateAnnotationInputGQL!]! | ||||||
|  |   ): UpdateShotAnnotationReturn! | ||||||
|  |   getProfileImageUploadLink( | ||||||
|  |     fileExt: String = ".png" | ||||||
|  |   ): GetProfileUploadLinkReturn! | ||||||
|  |   editProfileImageUri(profileImageUri: String!): UserGQL! | ||||||
|  |   editUser(input: EditUserInputGQL!): UserGQL! | ||||||
|  |   followUser(followedUserId: Int!): UserGQL! | ||||||
|  |   unfollowUser(followedUserId: Int!): UserGQL! | ||||||
|  |   createUploadStream( | ||||||
|  |     videoMetadata: VideoMetadataInput! | ||||||
|  |   ): CreateUploadStreamReturn! | ||||||
|  |   getUploadLink(videoId: Int!, segmentIndex: Int!): GetUploadLinkReturn! | ||||||
|  |   getHlsInitUploadLink(videoId: Int!): GetUploadLinkReturn! | ||||||
|  |   setSegmentDuration( | ||||||
|  |     videoId: Int! | ||||||
|  |     segmentIndex: Int! | ||||||
|  |     duration: Float! | ||||||
|  |   ): Boolean! | ||||||
|  |   editUploadStream(videoId: Int!, videoMetadata: VideoMetadataInput!): Boolean! | ||||||
|  |   deleteVideo(videoId: Int!): Boolean! | ||||||
| } | } | ||||||
|  |  | ||||||
| input CreateBucketSetInput { | input CreateBucketSetInput { | ||||||
| @@ -236,32 +637,139 @@ input CreateBucketSetInput { | |||||||
|   buckets: [BucketInputGQL!]! |   buckets: [BucketInputGQL!]! | ||||||
| } | } | ||||||
|  |  | ||||||
| type ProcessVideoSourceReturn { | type AddShotAnnotationReturn { | ||||||
|   val: Int! |   value: SuccessfulAddAddShotAnnotationErrors! | ||||||
| } | } | ||||||
|  |  | ||||||
| input ProcessVideoSourceInput { | union SuccessfulAddAddShotAnnotationErrors = | ||||||
|   val: Int! |     SuccessfulAdd | ||||||
|  |   | AddShotAnnotationErrors | ||||||
|  |  | ||||||
|  | type SuccessfulAdd { | ||||||
|  |   value: Boolean! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type AddShotAnnotationErrors { | ||||||
|  |   error: DoesNotOwnShotErrOtherErrorNeedsNote! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | union DoesNotOwnShotErrOtherErrorNeedsNote = | ||||||
|  |     DoesNotOwnShotErr | ||||||
|  |   | OtherErrorNeedsNote | ||||||
|  |  | ||||||
|  | type DoesNotOwnShotErr { | ||||||
|  |   shotId: Int! | ||||||
|  |   msg: String | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type OtherErrorNeedsNote { | ||||||
|  |   msg: String | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type UpdateShotAnnotationReturn { | ||||||
|  |   shot: ShotGQL | ||||||
|  |   error: DoesNotOwnShotErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input UpdateAnnotationInputGQL { | ||||||
|  |   name: String! | ||||||
|  |   notes: String = null | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type GetProfileUploadLinkReturn { | ||||||
|  |   value: UploadLinkGetProfileUploadLinkErrors! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | union UploadLinkGetProfileUploadLinkErrors = | ||||||
|  |     UploadLink | ||||||
|  |   | GetProfileUploadLinkErrors | ||||||
|  |  | ||||||
|  | type UploadLink { | ||||||
|  |   uploadUrl: String! | ||||||
|  |   headers: [Header]! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type Header { | ||||||
|  |   key: String! | ||||||
|  |   value: String! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type GetProfileUploadLinkErrors { | ||||||
|  |   error: TooManyProfileImageUploadsErr! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type TooManyProfileImageUploadsErr { | ||||||
|  |   linksRequested: Int! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input EditUserInputGQL { | ||||||
|  |   username: String = null | ||||||
|  |   fargoRating: Int = null | ||||||
| } | } | ||||||
|  |  | ||||||
| type CreateUploadStreamReturn { | type CreateUploadStreamReturn { | ||||||
|   videoId: Int! |   videoId: Int! | ||||||
| } | } | ||||||
|  |  | ||||||
| input UploadMetadataInput { | input VideoMetadataInput { | ||||||
|   deviceType: DeviceTypeEnum = null |   videoName: String = null | ||||||
|   osVersion: String = null |   startTime: DateTime = null | ||||||
|   appVersion: String = null |   endTime: DateTime = null | ||||||
|   browserName: String = null |   gameType: String = null | ||||||
|   browserVersion: String = null |   tableSize: Float = null | ||||||
|   locale: String = null |   lastIntendedSegmentBound: Int = null | ||||||
|   timezone: String = null |   streamSegmentType: StreamSegmentTypeEnum = null | ||||||
|   networkType: String = null |   endStream: Boolean! = false | ||||||
|   ipAddress: String = null |   resolution: VideoResolution = null | ||||||
|  |   framesPerSecond: Float = null | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input VideoResolution { | ||||||
|  |   width: Int! | ||||||
|  |   height: Int! | ||||||
| } | } | ||||||
|  |  | ||||||
| type GetUploadLinkReturn { | type GetUploadLinkReturn { | ||||||
|   uploadUrl: String! |   value: UploadLinkGetUploadLinkErrors! | ||||||
|   linksRequested: Int! |   stream: UploadStreamGQL | ||||||
|   uploadsCompleted: Int! | } | ||||||
|  |  | ||||||
|  | union UploadLinkGetUploadLinkErrors = UploadLink | GetUploadLinkErrors | ||||||
|  |  | ||||||
|  | type GetUploadLinkErrors { | ||||||
|  |   error: MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErr! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | union MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErr = | ||||||
|  |     MustHaveSetForUploadLinkErr | ||||||
|  |   | SegmentAlreadyUploadedErr | ||||||
|  |   | ProcessingFailedErr | ||||||
|  |   | NoInitForChunkedUploadErr | ||||||
|  |   | TooManyProfileImageUploadsErr | ||||||
|  |   | InitUploadAlreadyCompletedErr | ||||||
|  |   | TooManyInitUploadsErr | ||||||
|  |  | ||||||
|  | type MustHaveSetForUploadLinkErr { | ||||||
|  |   resolution: Boolean | ||||||
|  |   framesPerSecond: Boolean | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type SegmentAlreadyUploadedErr { | ||||||
|  |   segmentId: Int! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type ProcessingFailedErr { | ||||||
|  |   processing: VideoProcessingGQL! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type NoInitForChunkedUploadErr { | ||||||
|  |   segmentType: StreamSegmentTypeEnum! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type InitUploadAlreadyCompletedErr { | ||||||
|  |   segmentType: StreamSegmentTypeEnum! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type TooManyInitUploadsErr { | ||||||
|  |   linksRequested: Int! | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -1553,6 +1553,11 @@ colorette@^2.0.16: | |||||||
|   resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" |   resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" | ||||||
|   integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== |   integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== | ||||||
|  |  | ||||||
|  | commander@4.0.1: | ||||||
|  |   version "4.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/commander/-/commander-4.0.1.tgz#b67622721785993182e807f4883633e6401ba53c" | ||||||
|  |   integrity sha512-IPF4ouhCP+qdlcmCedhxX4xiGBPyigb8v5NeUp+0LyhwLgxMqyp3S0vl7TAPfS/hiP7FC3caI/PB9lTmP8r1NA== | ||||||
|  |  | ||||||
| common-tags@1.8.2: | common-tags@1.8.2: | ||||||
|   version "1.8.2" |   version "1.8.2" | ||||||
|   resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" |   resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" | ||||||
| @@ -2538,6 +2543,14 @@ path-type@^4.0.0: | |||||||
|   resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" |   resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" | ||||||
|   integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== |   integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== | ||||||
|  |  | ||||||
|  | pbjs@^0.0.14: | ||||||
|  |   version "0.0.14" | ||||||
|  |   resolved "https://registry.yarnpkg.com/pbjs/-/pbjs-0.0.14.tgz#5ab3d4a5f06a9ab78dd320c63f72877120d4c48d" | ||||||
|  |   integrity sha512-F4aA0ojrQ37kxFPOg4yRLP/vxb76rYQwMQigmVEljYlA7hZKmjaWjP6IkRn4nA0NdIj4Xxe4iqWrrIhJy+MwWQ== | ||||||
|  |   dependencies: | ||||||
|  |     commander "4.0.1" | ||||||
|  |     protocol-buffers-schema "3.1.0" | ||||||
|  |  | ||||||
| picocolors@^1.0.0: | picocolors@^1.0.0: | ||||||
|   version "1.0.0" |   version "1.0.0" | ||||||
|   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" |   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" | ||||||
| @@ -2548,6 +2561,16 @@ picomatch@^2.3.1: | |||||||
|   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" |   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" | ||||||
|   integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== |   integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== | ||||||
|  |  | ||||||
|  | prettier-plugin-organize-imports@^3.2.4: | ||||||
|  |   version "3.2.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz#77967f69d335e9c8e6e5d224074609309c62845e" | ||||||
|  |   integrity sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog== | ||||||
|  |  | ||||||
|  | prettier@^3.2.5: | ||||||
|  |   version "3.2.5" | ||||||
|  |   resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" | ||||||
|  |   integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== | ||||||
|  |  | ||||||
| promise@^7.1.1: | promise@^7.1.1: | ||||||
|   version "7.3.1" |   version "7.3.1" | ||||||
|   resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" |   resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" | ||||||
| @@ -2564,6 +2587,11 @@ prop-types@^15.7.2: | |||||||
|     object-assign "^4.1.1" |     object-assign "^4.1.1" | ||||||
|     react-is "^16.13.1" |     react-is "^16.13.1" | ||||||
|  |  | ||||||
|  | protocol-buffers-schema@3.1.0: | ||||||
|  |   version "3.1.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.1.0.tgz#d8a819549ead3e6bd189ebe9e50e96636bbc5cc7" | ||||||
|  |   integrity sha512-1g9zFjLFhGN1Dc5UVO8D2loVslp6sVxk5sJqgD66CuWUITh2gOaTLRN/pIakGFfB6e0nNF6hImrYFDurEsA1UQ== | ||||||
|  |  | ||||||
| punycode@^1.3.2: | punycode@^1.3.2: | ||||||
|   version "1.4.1" |   version "1.4.1" | ||||||
|   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" |   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user