diff --git a/UnimayProvider/build.gradle.kts b/UnimayProvider/build.gradle.kts
new file mode 100644
index 0000000..a9097e3
--- /dev/null
+++ b/UnimayProvider/build.gradle.kts
@@ -0,0 +1,25 @@
+// use an integer for version numbers
+version = 1
+
+cloudstream {
+ language = "uk"
+ // All of these properties are optional, you can safely remove them
+
+ description = "Unimay Media є однією з провідних команд, що спеціалізується на локалізації та озвученні аніме для україномовної аудиторії."
+ authors = listOf("CakesTwix")
+
+ /**
+ * Status int as the following:
+ * 0: Down
+ * 1: Ok
+ * 2: Slow
+ * 3: Beta only
+ * */
+ status = 1 // will be 3 if unspecified
+ tvTypes = listOf(
+ "Anime",
+ "AnimeMovie",
+ )
+
+ iconUrl = "https://www.google.com/s2/favicons?domain=unimay.media&sz=%size%"
+}
\ No newline at end of file
diff --git a/UnimayProvider/src/main/AndroidManifest.xml b/UnimayProvider/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..29aec9d
--- /dev/null
+++ b/UnimayProvider/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/UnimayProvider/src/main/kotlin/com/lagradost/UnimayProvider.kt b/UnimayProvider/src/main/kotlin/com/lagradost/UnimayProvider.kt
new file mode 100644
index 0000000..716feaa
--- /dev/null
+++ b/UnimayProvider/src/main/kotlin/com/lagradost/UnimayProvider.kt
@@ -0,0 +1,160 @@
+package com.lagradost
+
+import com.lagradost.cloudstream3.DubStatus
+import com.lagradost.cloudstream3.Episode
+import com.lagradost.cloudstream3.HomePageResponse
+import com.lagradost.cloudstream3.LoadResponse
+import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
+import com.lagradost.cloudstream3.MainAPI
+import com.lagradost.cloudstream3.MainPageRequest
+import com.lagradost.cloudstream3.SearchResponse
+import com.lagradost.cloudstream3.ShowStatus
+import com.lagradost.cloudstream3.SubtitleFile
+import com.lagradost.cloudstream3.TvType
+import com.lagradost.cloudstream3.addDubStatus
+import com.lagradost.cloudstream3.addEpisodes
+import com.lagradost.cloudstream3.app
+import com.lagradost.cloudstream3.mainPageOf
+import com.lagradost.cloudstream3.newAnimeLoadResponse
+import com.lagradost.cloudstream3.newAnimeSearchResponse
+import com.lagradost.cloudstream3.newHomePageResponse
+import com.lagradost.cloudstream3.utils.ExtractorLink
+import com.lagradost.cloudstream3.utils.M3u8Helper
+import com.lagradost.cloudstream3.utils.Qualities
+import com.lagradost.models.Releases
+import com.lagradost.models.SearchModel
+
+class UnimayProvider : MainAPI() {
+
+ // Basic Info
+ override var mainUrl = "https://www.unimay.media"
+ override var name = "Unimay"
+ override val hasMainPage = true
+ override var lang = "uk"
+ override val hasDownloadSupport = true
+ override val supportedTypes = setOf(
+ TvType.Anime,
+ TvType.AnimeMovie,
+ )
+
+ private val apiUrl = "https://api.unimay.media"
+ private val findUrl = "$apiUrl/api/release/search/?title="
+ private val imagesUrl = "$apiUrl/storage/images/"
+
+ // Sections
+ override val mainPage = mainPageOf(
+ "$apiUrl/api/release/all?page=" to "Останні релізи",
+ )
+
+ // Done
+ override suspend fun getMainPage(
+ page: Int,
+ request: MainPageRequest
+ ): HomePageResponse {
+ val homeList = app.get("${request.data}$page").parsedSafe()!!.releases.map{
+ newAnimeSearchResponse(it.name, "$apiUrl/api/release/${it.code}", TvType.Anime) {
+ this.posterUrl = "$imagesUrl${it.imageId}"
+ addDubStatus("${it.playlistSize}/${it.episodes}", it.playlistSize)
+ }
+ }
+
+ return newHomePageResponse(request.name, homeList)
+ }
+
+ override suspend fun search(query: String): List {
+ return app.get("$findUrl$query&page=1").parsedSafe()!!.releases.map{
+ newAnimeSearchResponse(it.name, "$apiUrl/api/release/${it.code}", TvType.Anime) {
+ this.posterUrl = "$imagesUrl${it.imageId}"
+ addDubStatus("${it.playlistSize}/${it.episodes}", it.playlistSize)
+ }
+ }
+ }
+
+ // Detailed information
+ override suspend fun load(url: String): LoadResponse {
+ val anime = app.get("$apiUrl/api/release/${url.substringAfterLast("/")}").parsedSafe()!!
+ // val anime = Gson().fromJson(app.get("$apiUrl/api/release/${url.substringAfterLast("/")}").text, SearchModel::class.java)
+
+ val showStatus = when(anime.statusCode){
+ 0 -> ShowStatus.Ongoing
+ else -> ShowStatus.Completed
+
+ }
+
+ val tvType = when(anime.type){
+ "Фільм" -> TvType.AnimeMovie
+ "Телесеріал" -> TvType.Anime
+ else -> TvType.Anime
+ }
+
+
+ val episodes = anime.playlist.map{
+ Episode(
+ "${anime.code}, ${it.number}",
+ it.title,
+ episode = it.number,
+ posterUrl = if(it.previewId != null) { "$imagesUrl${it.previewId}" } else null,
+ )
+ }
+
+ return newAnimeLoadResponse(
+ anime.name,
+ "$mainUrl/projects/${anime.code}",
+ tvType,
+ ) {
+ this.engName = anime.engName
+ this.posterUrl = "$imagesUrl${anime.posterId}"
+ this.tags = anime.genres
+ this.plot = anime.description
+ this.showStatus = showStatus
+ this.duration = anime.episodeLength
+ addEpisodes(DubStatus.Dubbed, episodes)
+ this.year = anime.year
+ addAniListId(anime.aniListId)
+ }
+ }
+
+ // It works when I click to view the series
+ override suspend fun loadLinks(
+ data: String,
+ isCasting: Boolean,
+ subtitleCallback: (SubtitleFile) -> Unit,
+ callback: (ExtractorLink) -> Unit
+ ): Boolean {
+ // anime_id, episode number
+ val dataList = data.split(", ")
+ // Log.d("CakesTwix-Debug", dataList.toString())
+
+ val anime = app.get("$apiUrl/api/release/${dataList[0]}").parsedSafe()!!
+ // val anime = Gson().fromJson(app.get("$apiUrl/api/release/${dataList[0]}").text, SearchModel::class.java)
+ val episode = anime.playlist.first { it.number == dataList[1].toInt() }
+
+ if (episode.playlist != null) {
+ M3u8Helper.generateM3u8(
+ source = "Unimay",
+ streamUrl = episode.playlist,
+ referer = "https://www.unimay.media"
+ ).forEach(callback)
+ return true
+ }
+
+ if (episode.sd != null) {
+ callback(ExtractorLink(episode.sd,"Unimay", episode.sd, "https://www.unimay.media",
+ Qualities.P480.value, false))
+ }
+ if (episode.hd != null) {
+ callback(ExtractorLink(episode.hd,"Unimay", episode.hd, "https://www.unimay.media",
+ Qualities.P720.value, false))
+ }
+ if (episode.fhd != null) {
+ callback(ExtractorLink(episode.fhd,"Unimay", episode.fhd, "https://www.unimay.media",
+ Qualities.P1080.value, false))
+ }
+ if (episode.qhd != null) {
+ callback(ExtractorLink(episode.qhd,"Unimay", episode.qhd, "https://www.unimay.media",
+ Qualities.P2160.value, false))
+ }
+
+ return true
+ }
+}
diff --git a/UnimayProvider/src/main/kotlin/com/lagradost/UnimayProviderPlugin.kt b/UnimayProvider/src/main/kotlin/com/lagradost/UnimayProviderPlugin.kt
new file mode 100644
index 0000000..87368ab
--- /dev/null
+++ b/UnimayProvider/src/main/kotlin/com/lagradost/UnimayProviderPlugin.kt
@@ -0,0 +1,13 @@
+package com.lagradost
+
+import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
+import com.lagradost.cloudstream3.plugins.Plugin
+import android.content.Context
+
+@CloudstreamPlugin
+class UnimayProviderPlugin: Plugin() {
+ override fun load(context: Context) {
+ // All providers should be added in this manner. Please don't edit the providers list directly.
+ registerMainAPI(UnimayProvider())
+ }
+}
\ No newline at end of file
diff --git a/UnimayProvider/src/main/kotlin/com/lagradost/models/Releases.kt b/UnimayProvider/src/main/kotlin/com/lagradost/models/Releases.kt
new file mode 100644
index 0000000..d60d691
--- /dev/null
+++ b/UnimayProvider/src/main/kotlin/com/lagradost/models/Releases.kt
@@ -0,0 +1,23 @@
+package com.lagradost.models
+
+data class Releases(
+
+ val titleCount : Int,
+ val releases : List
+)
+
+data class Release (
+
+ val id : Int,
+ val imageId : Int,
+ val episodes : Int,
+ val playlistSize : Int,
+ val episodeLength : Int,
+ val year : Int,
+ val restricted : Boolean,
+ val code : String,
+ val description : String,
+ val name : String,
+ val season : String,
+ val statusCode : Int
+)
diff --git a/UnimayProvider/src/main/kotlin/com/lagradost/models/Search.kt b/UnimayProvider/src/main/kotlin/com/lagradost/models/Search.kt
new file mode 100644
index 0000000..406aba2
--- /dev/null
+++ b/UnimayProvider/src/main/kotlin/com/lagradost/models/Search.kt
@@ -0,0 +1,81 @@
+package com.lagradost.models
+
+data class SearchModel (
+
+ val id : Int,
+ val aniListId : Int,
+ val episodes : Int,
+ val episodeLength : Int,
+ val year : Int,
+ val restricted : Boolean,
+ val active : Boolean,
+ val announce : String,
+ val code : String,
+ val tgCode : String,
+ val cdnCode : String,
+ val description : String,
+ val lastUpdate : Long,
+ val name : String,
+ val engName : String,
+ val trailer : String,
+ // https://api.unimay.media/api/release/suzume-locking-up-the-doors
+ // val trailerPlaylist : String?,
+ val timestamp : Long,
+ val season : String,
+ val type : String,
+ val posterId : Int,
+ val imageId : Int,
+ val genres : List,
+ val playlist : List,
+ val playlistSize : Int,
+ val actors : List,
+ val translators : List,
+ val soundmans : List,
+ val genresInString : String,
+ val statusCode : Int
+)
+
+data class Actors (
+
+ val id : Int,
+ val firstName : String,
+ val lastName : String,
+ val nickName : String,
+ val city : String,
+ val avtarId : Int
+)
+
+data class Playlist (
+
+ val id : Int,
+ val number : Int,
+ val title : String,
+ val preview : String?,
+ val previewId : Int?,
+ val sd : String?,
+ val hd : String?,
+ val fhd : String?,
+ val qhd : String?,
+ val playlist : String?,
+ val hidden : Boolean
+)
+
+data class Soundmans (
+
+ val id : Int,
+ val firstName : String,
+ val lastName : String,
+ val nickName : String,
+ val city : String,
+ val avtarId : Int
+)
+
+data class Translators (
+
+ val id : Int,
+ val firstName : String,
+ val lastName : String,
+ val nickName : String,
+ val city : String,
+ val avtarId : Int
+)
\ No newline at end of file