|
@@ -1,52 +1,41 @@
|
|
|
use crate::*;
|
|
|
|
|
|
-pub(crate) type ContentId<T> = <T as StorageOwnership>::ContentId;
|
|
|
-
|
|
|
-pub(crate) type DataObjectTypeId<T> = <T as StorageOwnership>::DataObjectTypeId;
|
|
|
-
|
|
|
-pub(crate) type DAOId<T> = <T as StorageOwnership>::DAOId;
|
|
|
-
|
|
|
-pub(crate) type ContentParameters<T> = ContentParametersRecord<ContentId<T>, DataObjectTypeId<T>>;
|
|
|
-
|
|
|
-pub(crate) type StorageObjectOwner<T> =
|
|
|
- StorageObjectOwnerRecord<MemberId<T>, <T as StorageOwnership>::ChannelId, DAOId<T>>;
|
|
|
-
|
|
|
-/// Type, used in diffrent numeric constraints representations
|
|
|
-pub type MaxNumber = u32;
|
|
|
-
|
|
|
/// Specifies how a new asset will be provided on creating and updating
|
|
|
/// Channels, Videos, Series and Person
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub enum NewAsset<ContentParameters> {
|
|
|
+pub enum NewAssetsRecord<Balance> {
|
|
|
/// Upload to the storage frame_system
|
|
|
- Upload(ContentParameters),
|
|
|
+ Upload(CreationUploadParameters<Balance>),
|
|
|
/// Multiple url strings pointing at an asset
|
|
|
- Urls(Vec<Url>),
|
|
|
+ Urls(Vec<AssetUrls>),
|
|
|
}
|
|
|
|
|
|
+pub type NewAssets<T> = NewAssetsRecord<<T as balances::Trait>::Balance>;
|
|
|
+
|
|
|
/// The owner of a channel, is the authorized "actor" that can update
|
|
|
/// or delete or transfer a channel and its contents.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub enum ChannelOwner<MemberId, CuratorGroupId, DAOId> {
|
|
|
+pub enum ChannelOwner<MemberId, CuratorGroupId> {
|
|
|
/// A Member owns the channel
|
|
|
Member(MemberId),
|
|
|
/// A specific curation group owns the channel
|
|
|
CuratorGroup(CuratorGroupId),
|
|
|
- // Native DAO owns the channel
|
|
|
- Dao(DAOId),
|
|
|
}
|
|
|
|
|
|
// simplification type
|
|
|
-pub(crate) type ActorToChannelOwnerResult<T> =
|
|
|
- Result<ChannelOwner<MemberId<T>, CuratorGroupId<T>, DAOId<T>>, Error<T>>;
|
|
|
+pub(crate) type ActorToChannelOwnerResult<T> = Result<
|
|
|
+ ChannelOwner<
|
|
|
+ <T as membership::Trait>::MemberId,
|
|
|
+ <T as ContentActorAuthenticator>::CuratorGroupId,
|
|
|
+ >,
|
|
|
+ Error<T>,
|
|
|
+>;
|
|
|
|
|
|
// Default trait implemented only because its used in a Channel which needs to implement a Default trait
|
|
|
// since it is a StorageValue.
|
|
|
-impl<MemberId: Default, CuratorGroupId, DAOId> Default
|
|
|
- for ChannelOwner<MemberId, CuratorGroupId, DAOId>
|
|
|
-{
|
|
|
+impl<MemberId: Default, CuratorGroupId> Default for ChannelOwner<MemberId, CuratorGroupId> {
|
|
|
fn default() -> Self {
|
|
|
ChannelOwner::Member(MemberId::default())
|
|
|
}
|
|
@@ -77,28 +66,24 @@ pub struct ChannelCategoryUpdateParameters {
|
|
|
}
|
|
|
|
|
|
/// Type representing an owned channel which videos, playlists, and series can belong to.
|
|
|
-/// If a channel is deleted, all videos, playlists and series will also be deleted.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct ChannelRecord<MemberId, CuratorGroupId, DAOId, AccountId, VideoId, PlaylistId, SeriesId>
|
|
|
-{
|
|
|
+pub struct ChannelRecord<MemberId, CuratorGroupId, AccountId> {
|
|
|
/// The owner of a channel
|
|
|
- pub owner: ChannelOwner<MemberId, CuratorGroupId, DAOId>,
|
|
|
+ pub owner: ChannelOwner<MemberId, CuratorGroupId>,
|
|
|
/// The videos under this channel
|
|
|
- pub videos: Vec<VideoId>,
|
|
|
- /// The playlists under this channel
|
|
|
- pub playlists: Vec<PlaylistId>,
|
|
|
- /// The series under this channel
|
|
|
- pub series: Vec<SeriesId>,
|
|
|
+ pub num_videos: u64,
|
|
|
/// If curators have censored this channel or not
|
|
|
pub is_censored: bool,
|
|
|
/// Reward account where revenue is sent if set.
|
|
|
pub reward_account: Option<AccountId>,
|
|
|
+ /// Account for withdrawing deletion prize funds
|
|
|
+ pub deletion_prize_source_account_id: AccountId,
|
|
|
+ /// Number of asset held in storage
|
|
|
+ pub num_assets: u64,
|
|
|
}
|
|
|
|
|
|
-impl<MemberId, CuratorGroupId, DAOId, AccountId, VideoId, PlaylistId, SeriesId>
|
|
|
- ChannelRecord<MemberId, CuratorGroupId, DAOId, AccountId, VideoId, PlaylistId, SeriesId>
|
|
|
-{
|
|
|
+impl<MemberId, CuratorGroupId, AccountId> ChannelRecord<MemberId, CuratorGroupId, AccountId> {
|
|
|
/// Ensure censorship status have been changed
|
|
|
pub fn ensure_censorship_status_changed<T: Trait>(&self, is_censored: bool) -> DispatchResult {
|
|
|
ensure!(
|
|
@@ -111,13 +96,9 @@ impl<MemberId, CuratorGroupId, DAOId, AccountId, VideoId, PlaylistId, SeriesId>
|
|
|
|
|
|
// Channel alias type for simplification.
|
|
|
pub type Channel<T> = ChannelRecord<
|
|
|
- MemberId<T>,
|
|
|
+ <T as membership::Trait>::MemberId,
|
|
|
<T as ContentActorAuthenticator>::CuratorGroupId,
|
|
|
- DAOId<T>,
|
|
|
<T as frame_system::Trait>::AccountId,
|
|
|
- <T as Trait>::VideoId,
|
|
|
- <T as Trait>::PlaylistId,
|
|
|
- <T as Trait>::SeriesId,
|
|
|
>;
|
|
|
|
|
|
/// A request to buy a channel by a new ChannelOwner.
|
|
@@ -127,22 +108,20 @@ pub struct ChannelOwnershipTransferRequestRecord<
|
|
|
ChannelId,
|
|
|
MemberId,
|
|
|
CuratorGroupId,
|
|
|
- DAOId,
|
|
|
Balance,
|
|
|
AccountId,
|
|
|
> {
|
|
|
- pub channel_id: ChannelId,
|
|
|
- pub new_owner: ChannelOwner<MemberId, CuratorGroupId, DAOId>,
|
|
|
- pub payment: Balance,
|
|
|
- pub new_reward_account: Option<AccountId>,
|
|
|
+ channel_id: ChannelId,
|
|
|
+ new_owner: ChannelOwner<MemberId, CuratorGroupId>,
|
|
|
+ payment: Balance,
|
|
|
+ new_reward_account: Option<AccountId>,
|
|
|
}
|
|
|
|
|
|
-/// ChannelOwnershipTransferRequest type alias for simplification.
|
|
|
+// ChannelOwnershipTransferRequest type alias for simplification.
|
|
|
pub type ChannelOwnershipTransferRequest<T> = ChannelOwnershipTransferRequestRecord<
|
|
|
- <T as StorageOwnership>::ChannelId,
|
|
|
- MemberId<T>,
|
|
|
+ <T as storage::Trait>::ChannelId,
|
|
|
+ <T as membership::Trait>::MemberId,
|
|
|
<T as ContentActorAuthenticator>::CuratorGroupId,
|
|
|
- DAOId<T>,
|
|
|
BalanceOf<T>,
|
|
|
<T as frame_system::Trait>::AccountId,
|
|
|
>;
|
|
@@ -150,41 +129,32 @@ pub type ChannelOwnershipTransferRequest<T> = ChannelOwnershipTransferRequestRec
|
|
|
/// Information about channel being created.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct ChannelCreationParameters<ContentParameters, AccountId> {
|
|
|
- /// Assets referenced by metadata
|
|
|
- pub assets: Vec<NewAsset<ContentParameters>>,
|
|
|
+pub struct ChannelCreationParametersRecord<NewAssets, AccountId> {
|
|
|
+ /// Asset collection for the channel, referenced by metadata
|
|
|
+ pub assets: NewAssets,
|
|
|
/// Metadata about the channel.
|
|
|
pub meta: Vec<u8>,
|
|
|
/// optional reward account
|
|
|
pub reward_account: Option<AccountId>,
|
|
|
}
|
|
|
|
|
|
+pub type ChannelCreationParameters<T> =
|
|
|
+ ChannelCreationParametersRecord<NewAssets<T>, <T as frame_system::Trait>::AccountId>;
|
|
|
+
|
|
|
/// Information about channel being updated.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct ChannelUpdateParameters<ContentParameters, AccountId> {
|
|
|
- /// Assets referenced by metadata
|
|
|
- pub assets: Option<Vec<NewAsset<ContentParameters>>>,
|
|
|
+pub struct ChannelUpdateParametersRecord<NewAssets, AccountId> {
|
|
|
+ /// Asset collection for the channel, referenced by metadata
|
|
|
+ pub assets: Option<NewAssets>,
|
|
|
/// If set, metadata update for the channel.
|
|
|
pub new_meta: Option<Vec<u8>>,
|
|
|
/// If set, updates the reward account of the channel
|
|
|
pub reward_account: Option<Option<AccountId>>,
|
|
|
}
|
|
|
|
|
|
-/// A category that videos can belong to.
|
|
|
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
-#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct VideoCategory {
|
|
|
- // No runtime information is currently stored for a Category.
|
|
|
-}
|
|
|
-
|
|
|
-/// Information about the video category being created.
|
|
|
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
-#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct VideoCategoryCreationParameters {
|
|
|
- /// Metadata about the video category.
|
|
|
- pub meta: Vec<u8>,
|
|
|
-}
|
|
|
+pub type ChannelUpdateParameters<T> =
|
|
|
+ ChannelUpdateParametersRecord<NewAssets<T>, <T as frame_system::Trait>::AccountId>;
|
|
|
|
|
|
/// Information about the video category being updated.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
@@ -195,244 +165,40 @@ pub struct VideoCategoryUpdateParameters {
|
|
|
pub new_meta: Vec<u8>,
|
|
|
}
|
|
|
|
|
|
+/// Information regarding the content being uploaded
|
|
|
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
|
|
|
+pub struct CreationUploadParameters<Balance> {
|
|
|
+ /// Data object parameters.
|
|
|
+ pub object_creation_list: Vec<DataObjectCreationParameters>,
|
|
|
+
|
|
|
+ /// Expected data size fee value for this extrinsic call.
|
|
|
+ pub expected_data_size_fee: Balance,
|
|
|
+}
|
|
|
+
|
|
|
/// Information about the video being created.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct VideoCreationParameters<ContentParameters> {
|
|
|
- /// Assets referenced by metadata
|
|
|
- pub assets: Vec<NewAsset<ContentParameters>>,
|
|
|
+pub struct VideoCreationParametersRecord<NewAssets> {
|
|
|
+ /// Asset collection for the video
|
|
|
+ pub assets: NewAssets,
|
|
|
/// Metadata for the video.
|
|
|
pub meta: Vec<u8>,
|
|
|
}
|
|
|
|
|
|
+pub type VideoCreationParameters<T> = VideoCreationParametersRecord<NewAssets<T>>;
|
|
|
+
|
|
|
+/// Information about the video being updated
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct VideoUpdateParameters<ContentParameters> {
|
|
|
+pub struct VideoUpdateParametersRecord<NewAssets> {
|
|
|
/// Assets referenced by metadata
|
|
|
- pub assets: Option<Vec<NewAsset<ContentParameters>>>,
|
|
|
+ pub assets: Option<NewAssets>,
|
|
|
/// If set, metadata update for the video.
|
|
|
pub new_meta: Option<Vec<u8>>,
|
|
|
}
|
|
|
|
|
|
-/// A video which belongs to a channel. A video may be part of a series or playlist.
|
|
|
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
-#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct VideoRecord<
|
|
|
- ChannelId,
|
|
|
- SeriesId,
|
|
|
- BlockNumber: BaseArithmetic + Copy,
|
|
|
- MemberId: Default + Copy + Ord,
|
|
|
- CuratorGroupId: Default + Copy,
|
|
|
- DAOId: Default + Copy,
|
|
|
- Balance: Default,
|
|
|
-> {
|
|
|
- pub in_channel: ChannelId,
|
|
|
- // keep track of which season the video is in if it is an 'episode'
|
|
|
- // - prevent removing a video if it is in a season (because order is important)
|
|
|
- pub in_series: Option<SeriesId>,
|
|
|
- /// Whether the curators have censored the video or not.
|
|
|
- pub is_censored: bool,
|
|
|
- /// Whether nft for this video have been issued.
|
|
|
- pub nft_status: Option<OwnedNFT<BlockNumber, MemberId, CuratorGroupId, DAOId, Balance>>,
|
|
|
-}
|
|
|
-
|
|
|
-impl<
|
|
|
- ChannelId: Clone,
|
|
|
- SeriesId: Clone,
|
|
|
- BlockNumber: BaseArithmetic + Copy,
|
|
|
- MemberId: Default + Copy + PartialEq + Ord,
|
|
|
- CuratorGroupId: Default + Copy + PartialEq,
|
|
|
- DAOId: Default + Copy + PartialEq,
|
|
|
- Balance: Clone + Default,
|
|
|
- > VideoRecord<ChannelId, SeriesId, BlockNumber, MemberId, CuratorGroupId, DAOId, Balance>
|
|
|
-{
|
|
|
- fn is_issued(&self) -> bool {
|
|
|
- self.nft_status.is_some()
|
|
|
- }
|
|
|
-
|
|
|
- /// Ensure nft status is set to `NoneIssued`
|
|
|
- pub fn ensure_nft_is_not_issued<T: Trait>(&self) -> DispatchResult {
|
|
|
- ensure!(!self.is_issued(), Error::<T>::NFTAlreadyExists);
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-
|
|
|
- /// Ensure nft status is set to `Owned`
|
|
|
- pub fn ensure_nft_is_issued<T: Trait>(&self) -> DispatchResult {
|
|
|
- ensure!(self.is_issued(), Error::<T>::NFTDoesNotExist);
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-
|
|
|
- /// Ensure given NFTOwner is nft owner
|
|
|
- pub fn ensure_nft_ownership<T: Trait>(
|
|
|
- &self,
|
|
|
- owner: &ChannelOwner<MemberId, CuratorGroupId, DAOId>,
|
|
|
- ) -> DispatchResult {
|
|
|
- if let Some(owned_nft) = &self.nft_status {
|
|
|
- ensure!(owned_nft.is_owner(owner), Error::<T>::DoesNotOwnNFT);
|
|
|
- }
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-
|
|
|
- /// Check whether nft transactional status is set to `Auction`
|
|
|
- pub fn is_nft_auction_started(&self) -> bool {
|
|
|
- matches!(
|
|
|
- self.nft_status,
|
|
|
- Some(OwnedNFT {
|
|
|
- transactional_status: TransactionalStatus::Auction(..),
|
|
|
- ..
|
|
|
- })
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
- /// Ensure nft is in auction state
|
|
|
- pub fn ensure_nft_auction_state<T: Trait>(
|
|
|
- &self,
|
|
|
- ) -> Result<AuctionRecord<BlockNumber, Balance, MemberId>, Error<T>> {
|
|
|
- if let Some(OwnedNFT {
|
|
|
- transactional_status: TransactionalStatus::Auction(auction),
|
|
|
- ..
|
|
|
- }) = &self.nft_status
|
|
|
- {
|
|
|
- Ok(auction.clone())
|
|
|
- } else {
|
|
|
- Err(Error::<T>::NotInAuctionState)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// Get nft auction record
|
|
|
- pub fn get_nft_auction(&self) -> Option<AuctionRecord<BlockNumber, Balance, MemberId>> {
|
|
|
- if let Some(OwnedNFT {
|
|
|
- transactional_status: TransactionalStatus::Auction(ref auction),
|
|
|
- ..
|
|
|
- }) = self.nft_status
|
|
|
- {
|
|
|
- Some(auction.clone())
|
|
|
- } else {
|
|
|
- None
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// Get nft auction record by reference
|
|
|
- pub fn get_nft_auction_ref(&self) -> Option<&AuctionRecord<BlockNumber, Balance, MemberId>> {
|
|
|
- if let Some(OwnedNFT {
|
|
|
- transactional_status: TransactionalStatus::Auction(ref auction),
|
|
|
- ..
|
|
|
- }) = self.nft_status
|
|
|
- {
|
|
|
- Some(auction)
|
|
|
- } else {
|
|
|
- None
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// Get nft auction record by mutable reference
|
|
|
- pub fn get_nft_auction_ref_mut(
|
|
|
- &mut self,
|
|
|
- ) -> Option<&mut AuctionRecord<BlockNumber, Balance, MemberId>> {
|
|
|
- if let Some(OwnedNFT {
|
|
|
- transactional_status: TransactionalStatus::Auction(ref mut auction),
|
|
|
- ..
|
|
|
- }) = self.nft_status
|
|
|
- {
|
|
|
- Some(auction)
|
|
|
- } else {
|
|
|
- None
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// Ensure nft transactional status is set to `Idle`
|
|
|
- pub fn ensure_nft_transactional_status_is_idle<T: Trait>(&self) -> DispatchResult {
|
|
|
- let is_idle = matches!(
|
|
|
- self.nft_status,
|
|
|
- Some(OwnedNFT {
|
|
|
- transactional_status: TransactionalStatus::Idle,
|
|
|
- ..
|
|
|
- })
|
|
|
- );
|
|
|
- ensure!(is_idle, Error::<T>::NftIsNotIdle);
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-
|
|
|
- /// Sets nft transactional status to `BuyNow`
|
|
|
- pub fn set_buy_now_transactionl_status(mut self, buy_now_price: Balance) -> Self {
|
|
|
- if let Some(owned_nft) = &mut self.nft_status {
|
|
|
- owned_nft.transactional_status = TransactionalStatus::BuyNow(buy_now_price);
|
|
|
- }
|
|
|
- self
|
|
|
- }
|
|
|
-
|
|
|
- /// Sets nft transactional status to provided `Auction`
|
|
|
- pub fn set_auction_transactional_status(
|
|
|
- mut self,
|
|
|
- auction: AuctionRecord<BlockNumber, Balance, MemberId>,
|
|
|
- ) -> Self {
|
|
|
- if let Some(owned_nft) = &mut self.nft_status {
|
|
|
- owned_nft.transactional_status = TransactionalStatus::Auction(auction);
|
|
|
- }
|
|
|
- self
|
|
|
- }
|
|
|
-
|
|
|
- /// Set nft transactional status to `Idle`
|
|
|
- pub fn set_idle_transactional_status(mut self) -> Self {
|
|
|
- if let Some(owned_nft) = &mut self.nft_status {
|
|
|
- owned_nft.transactional_status = TransactionalStatus::Idle;
|
|
|
- }
|
|
|
- self
|
|
|
- }
|
|
|
-
|
|
|
- /// Set nft transactional status to `InitiatedOfferToMember`
|
|
|
- pub fn set_pending_offer_transactional_status(
|
|
|
- mut self,
|
|
|
- to: MemberId,
|
|
|
- balance: Option<Balance>,
|
|
|
- ) -> Self {
|
|
|
- if let Some(owned_nft) = &mut self.nft_status {
|
|
|
- owned_nft.transactional_status =
|
|
|
- TransactionalStatus::InitiatedOfferToMember(to, balance);
|
|
|
- }
|
|
|
- self
|
|
|
- }
|
|
|
-
|
|
|
- /// Whether pending tansfer exist
|
|
|
- pub fn is_pending_offer_transactional_status(&self) -> bool {
|
|
|
- matches!(
|
|
|
- self.nft_status,
|
|
|
- Some(OwnedNFT {
|
|
|
- transactional_status: TransactionalStatus::InitiatedOfferToMember(..),
|
|
|
- ..
|
|
|
- })
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
- /// Ensure NFT has pending offer
|
|
|
- pub fn ensure_pending_offer_exists<T: Trait>(&self) -> DispatchResult {
|
|
|
- ensure!(
|
|
|
- self.is_pending_offer_transactional_status(),
|
|
|
- Error::<T>::PendingTransferDoesNotExist
|
|
|
- );
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-
|
|
|
- /// Ensure censorship status have been changed
|
|
|
- pub fn ensure_censorship_status_changed<T: Trait>(&self, is_censored: bool) -> DispatchResult {
|
|
|
- ensure!(
|
|
|
- self.is_censored != is_censored,
|
|
|
- Error::<T>::VideoCensorshipStatusDidNotChange
|
|
|
- );
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/// Video alias type for simplification.
|
|
|
-pub type Video<T> = VideoRecord<
|
|
|
- <T as StorageOwnership>::ChannelId,
|
|
|
- <T as Trait>::SeriesId,
|
|
|
- <T as frame_system::Trait>::BlockNumber,
|
|
|
- MemberId<T>,
|
|
|
- CuratorGroupId<T>,
|
|
|
- DAOId<T>,
|
|
|
- BalanceOf<T>,
|
|
|
->;
|
|
|
+pub type VideoUpdateParameters<T> = VideoUpdateParametersRecord<NewAssets<T>>;
|
|
|
|
|
|
/// Information about the plyalist being created.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
@@ -456,15 +222,15 @@ pub struct PlaylistUpdateParameters {
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
pub struct Playlist<ChannelId> {
|
|
|
/// The channel the playlist belongs to.
|
|
|
- pub in_channel: ChannelId,
|
|
|
+ in_channel: ChannelId,
|
|
|
}
|
|
|
|
|
|
/// Information about the episode being created or updated.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub enum EpisodeParameters<VideoId, ContentParameters> {
|
|
|
+pub enum EpisodeParameters<VideoId, NewAssets> {
|
|
|
/// A new video is being added as the episode.
|
|
|
- NewVideo(VideoCreationParameters<ContentParameters>),
|
|
|
+ NewVideo(VideoCreationParametersRecord<NewAssets>),
|
|
|
/// An existing video is being made into an episode.
|
|
|
ExistingVideo(VideoId),
|
|
|
}
|
|
@@ -472,49 +238,49 @@ pub enum EpisodeParameters<VideoId, ContentParameters> {
|
|
|
/// Information about the season being created or updated.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct SeasonParameters<VideoId, ContentParameters> {
|
|
|
+pub struct SeasonParameters<VideoId, NewAssets> {
|
|
|
/// Season assets referenced by metadata
|
|
|
- pub assets: Option<Vec<NewAsset<ContentParameters>>>,
|
|
|
+ pub assets: Option<NewAssets>,
|
|
|
// ?? It might just be more straighforward to always provide full list of episodes at cost of larger tx.
|
|
|
/// If set, updates the episodes of a season. Extends the number of episodes in a season
|
|
|
/// when length of new_episodes is greater than previously set. Last elements must all be
|
|
|
/// 'Some' in that case.
|
|
|
/// Will truncate existing season when length of new_episodes is less than previously set.
|
|
|
- pub episodes: Option<Vec<Option<EpisodeParameters<VideoId, ContentParameters>>>>,
|
|
|
- /// If set, Metadata update for season.
|
|
|
+ episodes: Option<Vec<Option<EpisodeParameters<VideoId, NewAssets>>>>,
|
|
|
+
|
|
|
pub meta: Option<Vec<u8>>,
|
|
|
}
|
|
|
|
|
|
/// Information about the series being created or updated.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct SeriesParameters<VideoId, ContentParameters> {
|
|
|
+pub struct SeriesParameters<VideoId, NewAssets> {
|
|
|
/// Series assets referenced by metadata
|
|
|
- pub assets: Option<Vec<NewAsset<ContentParameters>>>,
|
|
|
+ pub assets: Option<NewAssets>,
|
|
|
// ?? It might just be more straighforward to always provide full list of seasons at cost of larger tx.
|
|
|
/// If set, updates the seasons of a series. Extend a series when length of seasons is
|
|
|
/// greater than previoulsy set. Last elements must all be 'Some' in that case.
|
|
|
/// Will truncate existing series when length of seasons is less than previously set.
|
|
|
- pub seasons: Option<Vec<Option<SeasonParameters<VideoId, ContentParameters>>>>,
|
|
|
- pub meta: Option<Vec<u8>>,
|
|
|
+ seasons: Option<Vec<Option<SeasonParameters<VideoId, NewAssets>>>>,
|
|
|
+ meta: Option<Vec<u8>>,
|
|
|
}
|
|
|
|
|
|
/// A season is an ordered list of videos (episodes).
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
pub struct Season<VideoId> {
|
|
|
- pub episodes: Vec<VideoId>,
|
|
|
+ episodes: Vec<VideoId>,
|
|
|
}
|
|
|
|
|
|
/// A series is an ordered list of seasons that belongs to a channel.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
pub struct Series<ChannelId, VideoId> {
|
|
|
- pub in_channel: ChannelId,
|
|
|
- pub seasons: Vec<Season<VideoId>>,
|
|
|
+ in_channel: ChannelId,
|
|
|
+ seasons: Vec<Season<VideoId>>,
|
|
|
}
|
|
|
|
|
|
-// The actor the caller/origin is trying to act as for Person creation and update and delete calls.
|
|
|
+/// The actor the caller/origin is trying to act as for Person creation and update and delete calls.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
|
|
|
pub enum PersonActor<MemberId, CuratorId> {
|
|
@@ -532,8 +298,8 @@ pub enum PersonController<MemberId> {
|
|
|
Curators,
|
|
|
}
|
|
|
|
|
|
-// Default trait implemented only because its used in Person which needs to implement a Default trait
|
|
|
-// since it is a StorageValue.
|
|
|
+/// Default trait implemented only because its used in Person which needs to implement a Default trait
|
|
|
+/// since it is a StorageValue.
|
|
|
impl<MemberId: Default> Default for PersonController<MemberId> {
|
|
|
fn default() -> Self {
|
|
|
PersonController::Member(MemberId::default())
|
|
@@ -543,21 +309,21 @@ impl<MemberId: Default> Default for PersonController<MemberId> {
|
|
|
/// Information for Person being created.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct PersonCreationParameters<ContentParameters> {
|
|
|
+pub struct PersonCreationParameters<NewAssets> {
|
|
|
/// Assets referenced by metadata
|
|
|
- pub assets: Vec<NewAsset<ContentParameters>>,
|
|
|
+ pub assets: NewAssets,
|
|
|
/// Metadata for person.
|
|
|
- pub meta: Vec<u8>,
|
|
|
+ meta: Vec<u8>,
|
|
|
}
|
|
|
|
|
|
/// Information for Persion being updated.
|
|
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
-pub struct PersonUpdateParameters<ContentParameters> {
|
|
|
+pub struct PersonUpdateParameters<NewAssets> {
|
|
|
/// Assets referenced by metadata
|
|
|
- pub assets: Option<Vec<NewAsset<ContentParameters>>>,
|
|
|
+ pub assets: Option<NewAssets>,
|
|
|
/// Metadata to update person.
|
|
|
- pub new_meta: Option<Vec<u8>>,
|
|
|
+ new_meta: Option<Vec<u8>>,
|
|
|
}
|
|
|
|
|
|
/// A Person represents a real person that may be associated with a video.
|
|
@@ -567,3 +333,99 @@ pub struct Person<MemberId> {
|
|
|
/// Who can update or delete this person.
|
|
|
pub controlled_by: PersonController<MemberId>,
|
|
|
}
|
|
|
+
|
|
|
+/// A category that videos can belong to.
|
|
|
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
+pub struct VideoCategory {
|
|
|
+ // No runtime information is currently stored for a Category.
|
|
|
+}
|
|
|
+
|
|
|
+/// Information about the video category being created.
|
|
|
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
+pub struct VideoCategoryCreationParameters {
|
|
|
+ /// Metadata about the video category.
|
|
|
+ pub meta: Vec<u8>,
|
|
|
+}
|
|
|
+
|
|
|
+/// A video which belongs to a channel. A video may be part of a series or playlist.
|
|
|
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
|
|
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
|
|
|
+pub struct VideoRecord<
|
|
|
+ ChannelId,
|
|
|
+ SeriesId,
|
|
|
+ DataObjectId: Ord,
|
|
|
+ BlockNumber: BaseArithmetic + Copy + Default,
|
|
|
+ MemberId: Default + Copy + Ord,
|
|
|
+ AccountId: Default + Clone + Ord,
|
|
|
+ Balance: Default + Clone + BaseArithmetic,
|
|
|
+> {
|
|
|
+ pub in_channel: ChannelId,
|
|
|
+ // keep track of which season the video is in if it is an 'episode'
|
|
|
+ // - prevent removing a video if it is in a season (because order is important)
|
|
|
+ pub in_series: Option<SeriesId>,
|
|
|
+ /// Whether the curators have censored the video or not.
|
|
|
+ pub is_censored: bool,
|
|
|
+ /// storage parameters used during deletion
|
|
|
+ pub maybe_data_objects_id_set: Option<BTreeSet<DataObjectId>>,
|
|
|
+ /// Whether nft for this video have been issued.
|
|
|
+ pub nft_status: Option<OwnedNFT<BlockNumber, MemberId, AccountId, Balance>>,
|
|
|
+}
|
|
|
+
|
|
|
+impl<
|
|
|
+ ChannelId: Clone,
|
|
|
+ SeriesId: Clone,
|
|
|
+ DataObjectId: Ord,
|
|
|
+ BlockNumber: BaseArithmetic + Copy + Default,
|
|
|
+ MemberId: Default + Copy + PartialEq + Ord,
|
|
|
+ AccountId: Default + Clone + PartialEq + Ord,
|
|
|
+ Balance: Clone + Default + BaseArithmetic,
|
|
|
+ > VideoRecord<ChannelId, SeriesId, DataObjectId, BlockNumber, MemberId, AccountId, Balance>
|
|
|
+{
|
|
|
+ /// Ensure nft is not issued
|
|
|
+ pub fn ensure_nft_is_not_issued<T: Trait>(&self) -> DispatchResult {
|
|
|
+ ensure!(self.nft_status.is_none(), Error::<T>::NFTAlreadyExists);
|
|
|
+ Ok(())
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Ensure nft is issued
|
|
|
+ pub fn ensure_nft_is_issued<T: Trait>(
|
|
|
+ &self,
|
|
|
+ ) -> Result<OwnedNFT<BlockNumber, MemberId, AccountId, Balance>, Error<T>> {
|
|
|
+ if let Some(owned_nft) = &self.nft_status {
|
|
|
+ Ok(owned_nft.to_owned())
|
|
|
+ } else {
|
|
|
+ Err(Error::<T>::NFTDoesNotExist)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Set video nft status
|
|
|
+ pub fn set_nft_status(
|
|
|
+ mut self,
|
|
|
+ nft: OwnedNFT<BlockNumber, MemberId, AccountId, Balance>,
|
|
|
+ ) -> Self {
|
|
|
+ self.nft_status = Some(nft);
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Ensure censorship status have been changed
|
|
|
+ pub fn ensure_censorship_status_changed<T: Trait>(&self, is_censored: bool) -> DispatchResult {
|
|
|
+ ensure!(
|
|
|
+ self.is_censored != is_censored,
|
|
|
+ Error::<T>::VideoCensorshipStatusDidNotChange
|
|
|
+ );
|
|
|
+ Ok(())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// Video alias type for simplification.
|
|
|
+pub type Video<T> = VideoRecord<
|
|
|
+ <T as storage::Trait>::ChannelId,
|
|
|
+ <T as Trait>::SeriesId,
|
|
|
+ <T as storage::Trait>::DataObjectId,
|
|
|
+ <T as frame_system::Trait>::BlockNumber,
|
|
|
+ MemberId<T>,
|
|
|
+ <T as frame_system::Trait>::AccountId,
|
|
|
+ BalanceOf<T>,
|
|
|
+>;
|